foobara-agent 0.0.14 → 0.0.16

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: dc32aeaa66ec947920e085944f7948d22d97b4fa3b39d1a4b4fbf58755ca4321
4
- data.tar.gz: 0dc7b3d02061bf0a615ab6299ea5f607fff1d703804d5368b57a9157d4edf64a
3
+ metadata.gz: 240c7fa690a890cd583288e9ed1ae2fb7fe5c70a5322778eccf29ac4bc6554f9
4
+ data.tar.gz: 1d41b1f61ef8126fda960b91231558cf3911fc91a806e005d6c1d36db17d16d6
5
5
  SHA512:
6
- metadata.gz: e1a1d3780d7a3112cff93e7e626ec677ad558ce605e65c60f00ec3b8213b604e248ca4428311303b1902451f2bcc7d2a5f17f3725dde77bbb4725aeb10b9898d
7
- data.tar.gz: f6113517024dc34e999fafcb3bc5ee0ec98fb63628f61725b5631e454d6edd4714933a745232e57f2a1c8f686f0d2544b481b1726cfff3e4dbbc47666bdd74c4
6
+ metadata.gz: c02671a8ad44659aa2c5aed14bf57f71d3bf14252757302d040e4e2b6060b89c3cbccbc54e35e647cd2c5433a03ef15b12c7dcb97c602fcf4d5edb153d7b2c01
7
+ data.tar.gz: 7b250f7059fb4fda74fff80c4b7c886219abe44b234b48e41a54b954df20a7f549b161cada201b9215d259f17ace85c2ad174f3c95631f45c1ce7c6e965bffa1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [0.0.16] - 2025-07-09
2
+
3
+ - Tell the llm about previous goals
4
+ - Allow agents to be nameless
5
+ - Improve support for killing a running agent
6
+
7
+ ## [0.0.15] - 2025-07-09
8
+
9
+ - Make use of Ai.default_llm_model
10
+
1
11
  ## [0.0.14] - 2025-07-08
2
12
 
3
13
  - Better handle serialization/pre-commit loading for various entity-depth scenarios
@@ -25,8 +25,8 @@ module Foobara
25
25
  description: "Maximum number of commands to run before giving up"
26
26
  llm_model :string,
27
27
  :allow_nil,
28
- one_of: Foobara::Ai::AnswerBot::Types::ModelEnum,
29
- default: "claude-3-7-sonnet-20250219",
28
+ one_of: Ai::AnswerBot::Types::ModelEnum,
29
+ default: Ai.default_llm_model,
30
30
  description: "The model to use for the LLM"
31
31
  max_llm_calls_per_minute :integer, :allow_nil
32
32
  user_association_depth :symbol, :allow_nil, one_of: Foobara::AssociationDepth
@@ -48,7 +48,7 @@ module Foobara
48
48
  end
49
49
  # simulate_describe_command_run_for_all_commands
50
50
 
51
- until mission_accomplished or given_up
51
+ until mission_accomplished or given_up or killed
52
52
  increment_command_calls
53
53
  check_if_too_many_calls
54
54
 
@@ -69,7 +69,7 @@ module Foobara
69
69
  attr_accessor :next_command_name, :next_command_inputs, :next_command_raw_inputs, :mission_accomplished,
70
70
  :given_up, :next_command_class, :next_command, :command_outcome, :timed_out,
71
71
  :final_result, :final_message, :command_response, :delayed_command_name,
72
- :command_calls
72
+ :command_calls, :killed
73
73
 
74
74
  def list_commands_already_ran?
75
75
  context.command_log.any? { |log_entry| log_entry.command_name =~ /\bListCommands\z/ }
@@ -131,6 +131,8 @@ module Foobara
131
131
  end
132
132
 
133
133
  def determine_next_command_and_inputs(retries = 3, error_outcome = nil)
134
+ return if killed
135
+
134
136
  if retries == 0
135
137
  # TODO: test this path by irreparably breaking the needed commands
136
138
  # :nocov:
@@ -439,6 +441,10 @@ module Foobara
439
441
  self.final_message = message
440
442
  end
441
443
 
444
+ def kill!
445
+ self.killed = true
446
+ end
447
+
442
448
  def give_up!(message)
443
449
  self.given_up = true
444
450
  self.final_message = message
@@ -10,7 +10,7 @@ module Foobara
10
10
  agent Agent, :required
11
11
  llm_model :string,
12
12
  one_of: Foobara::Ai::AnswerBot::Types::ModelEnum,
13
- default: "claude-3-7-sonnet-20250219",
13
+ default: Ai.default_llm_model,
14
14
  description: "The model to use for the LLM"
15
15
  end
16
16
 
@@ -57,7 +57,15 @@ module Foobara
57
57
  end
58
58
 
59
59
  def goal
60
- context.current_goal
60
+ context.current_goal.text
61
+ end
62
+
63
+ def previous_goal_and_status_pairs
64
+ if context.previous_goals && !context.previous_goals.empty?
65
+ context.previous_goals.map do |previous_goal|
66
+ [previous_goal.text, previous_goal.state]
67
+ end
68
+ end
61
69
  end
62
70
 
63
71
  def context
@@ -4,19 +4,19 @@ module Foobara
4
4
  class Agent < CommandConnector
5
5
  class DetermineNextCommandNameAndInputs < DetermineBase
6
6
  class << self
7
- def llm_instructions(assistant_association_depth, goal)
8
- key = [assistant_association_depth, goal]
7
+ def llm_instructions(assistant_association_depth, goal, previous_goals = nil)
8
+ key = [assistant_association_depth, goal, previous_goals]
9
9
 
10
10
  @llm_instructions_cache ||= {}
11
11
 
12
12
  if @llm_instructions_cache.key?(key)
13
13
  @llm_instructions_cache[key]
14
14
  else
15
- @llm_instructions_cache[key] = build_llm_instructions(assistant_association_depth, goal)
15
+ @llm_instructions_cache[key] = build_llm_instructions(assistant_association_depth, goal, previous_goals)
16
16
  end
17
17
  end
18
18
 
19
- def build_llm_instructions(assistant_association_depth, goal)
19
+ def build_llm_instructions(assistant_association_depth, goal, previous_goals)
20
20
  instructions = "You are the implementation of a command called #{scoped_full_name}"
21
21
 
22
22
  instructions += if description && !description.empty?
@@ -29,7 +29,17 @@ module Foobara
29
29
 
30
30
  result_schema = result_json_schema(assistant_association_depth)
31
31
 
32
+ if previous_goals && !previous_goals.empty?
33
+ instructions += "You have previously accomplished the following goals:\n\n"
34
+
35
+ previous_goals.each.with_index do |(previous_goal, state), index|
36
+ instructions += "previous goal #{index + 1}: #{previous_goal}\n"
37
+ instructions += "status of goal #{index + 1}: #{state}\n\n"
38
+ end
39
+ end
40
+
32
41
  instructions += "You are working towards accomplishing the following goal:\n\n#{goal}\n\n"
42
+
33
43
  instructions += "Your response of which command to run next should match the following JSON schema:"
34
44
  instructions += "\n\n#{result_schema}\n\n"
35
45
  instructions += "You can get more details about the inputs and result schemas for a specific command by " \
@@ -52,7 +62,11 @@ module Foobara
52
62
  end
53
63
 
54
64
  def determine_llm_instructions
55
- self.llm_instructions = self.class.llm_instructions(computed_user_association_depth, goal)
65
+ self.llm_instructions = self.class.llm_instructions(
66
+ computed_user_association_depth,
67
+ goal,
68
+ previous_goal_and_status_pairs
69
+ )
56
70
  end
57
71
  end
58
72
  end
@@ -1,15 +1,17 @@
1
+ require_relative "goal"
2
+
1
3
  module Foobara
2
4
  class Agent < CommandConnector
3
5
  class Context < Foobara::Model
4
6
  class << self
5
7
  def for(goal)
6
- new(command_log: [], current_goal: goal)
8
+ new(command_log: [], current_goal: Goal.new(text: goal))
7
9
  end
8
10
  end
9
11
 
10
12
  attributes do
11
- current_goal :string, :required, "The current goal the agent needs to accomplish"
12
- previous_goals [:string]
13
+ current_goal Goal, :required, "The current goal the agent needs to accomplish"
14
+ previous_goals [Goal]
13
15
  # TODO: why doesn't this default of [] work as expected on newly created models?
14
16
  command_log [CommandLogEntry], default: [],
15
17
  description: "Log of all commands run so far and their outcomes"
@@ -18,7 +20,7 @@ module Foobara
18
20
  def set_new_goal(goal)
19
21
  self.previous_goals ||= []
20
22
  previous_goals << current_goal
21
- self.current_goal = goal
23
+ self.current_goal = Goal.new(text: goal)
22
24
  end
23
25
  end
24
26
  end
@@ -0,0 +1,18 @@
1
+ module Foobara
2
+ class Agent < CommandConnector
3
+ class Goal < Foobara::Model
4
+ module States
5
+ ACCOMPLISHED = :accomplished
6
+ KILLED = :killed
7
+ FAILED = :failed
8
+ ERROR = :error
9
+ GAVE_UP = :gave_up
10
+ end
11
+
12
+ attributes do
13
+ text :string, :required
14
+ state :symbol, :allow_nil, one_of: States
15
+ end
16
+ end
17
+ end
18
+ end
data/src/foobara/agent.rb CHANGED
@@ -15,6 +15,7 @@ module Foobara
15
15
 
16
16
  attr_accessor :context,
17
17
  :agent_name,
18
+ :agent_id,
18
19
  :llm_model,
19
20
  :current_accomplish_goal_command,
20
21
  :result_type,
@@ -44,8 +45,11 @@ module Foobara
44
45
  )
45
46
  # TODO: shouldn't have to pass command_log here since it has a default, debug that
46
47
  self.context = context
47
- self.agent_name = agent_name || "Anon#{SecureRandom.hex(2)}"
48
- self.llm_model = llm_model || "claude-opus-4-20250514"
48
+ if agent_name
49
+ self.agent_name = agent_name
50
+ end
51
+ self.agent_id = agent_name || "Anon#{SecureRandom.hex(2)}"
52
+ self.llm_model = llm_model || Ai.default_llm_model
49
53
  self.result_type = result_type
50
54
  self.include_message_to_user_in_result = include_message_to_user_in_result
51
55
  self.verbose = verbose
@@ -105,11 +109,16 @@ module Foobara
105
109
  end
106
110
 
107
111
  def kill!
108
- state_machine.perform_transition!(:kill)
112
+ current_accomplish_goal_command&.kill!
113
+ state_machine.perform_transition!(:kill) do
114
+ if context
115
+ context.current_goal.state = Goal::States::KILLED
116
+ end
117
+ end
109
118
  end
110
119
 
111
120
  def killed?
112
- state_machine.current_state == :killed
121
+ state_machine.current_state == Goal::States::KILLED
113
122
  end
114
123
 
115
124
  def accomplish_goal(
@@ -149,14 +158,27 @@ module Foobara
149
158
  transition = if outcome.success?
150
159
  :goal_accomplished
151
160
  else
152
- :goal_errored
161
+ :goal_failed
153
162
  end
154
163
 
155
- state_machine.perform_transition!(transition)
164
+ unless killed?
165
+ state_machine.perform_transition!(transition) do
166
+ context.current_goal.state = if outcome.success?
167
+ Goal::States::ACCOMPLISHED
168
+ else
169
+ Goal::States::FAILED
170
+ end
171
+ end
172
+ end
156
173
  end
157
174
  rescue
158
175
  # :nocov:
159
- state_machine.perform_transition!(:goal_failed)
176
+ unless killed?
177
+ state_machine.perform_transition!(:goal_errored) do
178
+ context.current_goal.state = Goal::States::ERROR
179
+ end
180
+ end
181
+
160
182
  raise
161
183
  # :nocov:
162
184
  end
@@ -247,7 +269,7 @@ module Foobara
247
269
  # TODO: Support changing the final result type when the goal changes
248
270
  NotifyUserThatCurrentGoalHasBeenAccomplished.for(
249
271
  result_type:,
250
- agent_id: agent_name,
272
+ agent_id:,
251
273
  # TODO: Support changing this flag when the goal changes
252
274
  include_message_to_user_in_result:,
253
275
  result_entity_depth:
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.14
4
+ version: 0.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -13,30 +13,42 @@ dependencies:
13
13
  name: foobara
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.126
18
+ version: 0.0.136
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.0
19
22
  type: :runtime
20
23
  prerelease: false
21
24
  version_requirements: !ruby/object:Gem::Requirement
22
25
  requirements:
23
- - - "~>"
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 0.0.136
29
+ - - "<"
24
30
  - !ruby/object:Gem::Version
25
- version: 0.0.126
31
+ version: 2.0.0
26
32
  - !ruby/object:Gem::Dependency
27
33
  name: foobara-llm-backed-command
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
30
- - - "~>"
36
+ - - ">="
31
37
  - !ruby/object:Gem::Version
32
38
  version: 1.0.0
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: 2.0.0
33
42
  type: :runtime
34
43
  prerelease: false
35
44
  version_requirements: !ruby/object:Gem::Requirement
36
45
  requirements:
37
- - - "~>"
46
+ - - ">="
38
47
  - !ruby/object:Gem::Version
39
48
  version: 1.0.0
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: 2.0.0
40
52
  email:
41
53
  - azimux@gmail.com
42
54
  executables: []
@@ -61,6 +73,7 @@ files:
61
73
  - src/foobara/agent/notify_user_that_current_goal_has_been_accomplished.rb
62
74
  - src/foobara/agent/types/command_log_entry.rb
63
75
  - src/foobara/agent/types/context.rb
76
+ - src/foobara/agent/types/goal.rb
64
77
  homepage: https://github.com/foobara/agent
65
78
  licenses:
66
79
  - MPL-2.0