ruby-openai-swarm 0.2.9 → 0.3.0.1
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/Gemfile.lock +1 -1
- data/examples/airline/main.rb +1 -1
- data/examples/basic/function_calling.rb +17 -1
- data/lib/ruby-openai-swarm/agent.rb +7 -1
- data/lib/ruby-openai-swarm/agents/change_tracker.rb +24 -0
- data/lib/ruby-openai-swarm/agents/strategy_options.rb +11 -0
- data/lib/ruby-openai-swarm/core.rb +14 -3
- data/lib/ruby-openai-swarm/util.rb +8 -0
- data/lib/ruby-openai-swarm/version.rb +1 -1
- data/lib/ruby-openai-swarm.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98aa27742c5ae980d9c1c8b9457beb2e61a4ff3a1548790d4205cd0f68cef039
|
4
|
+
data.tar.gz: 37d7a5280f47c2a454a2aba4a5f64587787f1e829fc07b6c27accc90f63f91f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d671ef9fa72e895bfd3b3e62561fccfc3894a6f19605dd43e68da14b0c9f958d22559da8d9eecd981277a7db035ed39c17535f261cf40849f16a95ac6884516
|
7
|
+
data.tar.gz: 96c6229510613dbb8b858200916bb9ab22583b7918d604adae0b1bc85bb5b89cfae28a6c833b8c16b2acc1758d1d89643c61f240c896ff6d1d3153536801b46d
|
data/Gemfile.lock
CHANGED
data/examples/airline/main.rb
CHANGED
@@ -65,4 +65,4 @@ params:
|
|
65
65
|
GUIDE_EXAMPLES
|
66
66
|
puts guide_examples
|
67
67
|
|
68
|
-
OpenAISwarm::Repl.run_demo_loop(triage_agent, context_variables: context_variables, debug: env_debug)
|
68
|
+
OpenAISwarm::Repl.run_demo_loop(triage_agent, context_variables: context_variables, stream: true, debug: env_debug)
|
@@ -46,6 +46,7 @@ Details:
|
|
46
46
|
Example: “What’s the weather in NYC?”
|
47
47
|
Action: Calls get_weather with location “New York City”.
|
48
48
|
Response: Only provides weather details.
|
49
|
+
|
49
50
|
2. Multiple Function Calls
|
50
51
|
Example: “Tell me the weather in New York and the latest news headlines.”
|
51
52
|
Action: Calls get_weather for weather and get_news for news.
|
@@ -58,4 +59,19 @@ GUIDE_EXAMPLES
|
|
58
59
|
|
59
60
|
puts guide_examples
|
60
61
|
|
61
|
-
OpenAISwarm::Repl.run_demo_loop(agent, stream: true, debug: env_debug)
|
62
|
+
# OpenAISwarm::Repl.run_demo_loop(agent, stream: true, debug: env_debug)
|
63
|
+
|
64
|
+
OpenAISwarm.new.run_and_stream(
|
65
|
+
agent: agent,
|
66
|
+
debug: true,
|
67
|
+
messages: [{"role" => "user", "content" => "Tell me the weather in New York and the latest news headlines."}]
|
68
|
+
) do |chunk|
|
69
|
+
if chunk.key?("content") && !chunk["content"].nil?
|
70
|
+
puts ">>>#{chunk}"
|
71
|
+
end
|
72
|
+
|
73
|
+
if chunk.key?('response')
|
74
|
+
binding.pry
|
75
|
+
# log_llm_request(chunk['response'])
|
76
|
+
end
|
77
|
+
end
|
@@ -3,7 +3,9 @@ module OpenAISwarm
|
|
3
3
|
attr_accessor :name, :model, :instructions,
|
4
4
|
:functions, :tool_choice,
|
5
5
|
:parallel_tool_calls,
|
6
|
+
:strategy,
|
6
7
|
:noisy_tool_calls,
|
8
|
+
:temperature,
|
7
9
|
:resource
|
8
10
|
# These attributes can be read and written externally. They include:
|
9
11
|
# - name: The name of the agent.
|
@@ -19,18 +21,22 @@ module OpenAISwarm
|
|
19
21
|
instructions: "You are a helpful agent.",
|
20
22
|
functions: [],
|
21
23
|
tool_choice: nil,
|
24
|
+
temperature: nil,
|
22
25
|
parallel_tool_calls: true,
|
23
26
|
resource: nil,
|
24
|
-
noisy_tool_calls: []
|
27
|
+
noisy_tool_calls: [],
|
28
|
+
strategy: {}
|
25
29
|
)
|
26
30
|
@name = name
|
27
31
|
@model = model
|
28
32
|
@instructions = instructions
|
29
33
|
@functions = functions
|
30
34
|
@tool_choice = tool_choice
|
35
|
+
@temperature = temperature
|
31
36
|
@parallel_tool_calls = parallel_tool_calls
|
32
37
|
@resource = resource
|
33
38
|
@noisy_tool_calls = noisy_tool_calls
|
39
|
+
@strategy = Agents::StrategyOptions.new(strategy)
|
34
40
|
end
|
35
41
|
end
|
36
42
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module OpenAISwarm
|
2
|
+
module Agents
|
3
|
+
class ChangeTracker
|
4
|
+
attr_reader :current_agent, :previous_agent
|
5
|
+
|
6
|
+
def initialize(agent)
|
7
|
+
update(agent)
|
8
|
+
end
|
9
|
+
|
10
|
+
def update(agent)
|
11
|
+
@previous_agent = @current_agent
|
12
|
+
@current_agent = agent
|
13
|
+
end
|
14
|
+
|
15
|
+
def agent_changed?
|
16
|
+
previous_agent&.name != current_agent&.name
|
17
|
+
end
|
18
|
+
|
19
|
+
def switch_agent_reset_message?
|
20
|
+
agent_changed? && current_agent.strategy.switch_agent_reset_message
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -14,7 +14,8 @@ module OpenAISwarm
|
|
14
14
|
@logger = OpenAISwarm::Logger.instance.logger
|
15
15
|
end
|
16
16
|
|
17
|
-
def get_chat_completion(
|
17
|
+
def get_chat_completion(agent_tracker, history, context_variables, model_override, stream, debug)
|
18
|
+
agent = agent_tracker.current_agent
|
18
19
|
context_variables = context_variables.dup
|
19
20
|
instructions = agent.instructions.respond_to?(:call) ? agent.instructions.call(context_variables) : agent.instructions
|
20
21
|
messages = [{ role: 'system', content: instructions }] + history
|
@@ -41,6 +42,7 @@ module OpenAISwarm
|
|
41
42
|
# create_params[:functions] = tools unless tools.empty?
|
42
43
|
# create_params[:function_call] = agent.tool_choice if agent.tool_choice
|
43
44
|
|
45
|
+
create_params[:temperature] = agent.temperature if agent.temperature
|
44
46
|
create_params[:tool_choice] = agent.tool_choice if agent.tool_choice
|
45
47
|
create_params[:parallel_tool_calls] = agent.parallel_tool_calls if tools.any?
|
46
48
|
|
@@ -146,6 +148,7 @@ module OpenAISwarm
|
|
146
148
|
end
|
147
149
|
|
148
150
|
def run(agent:, messages:, context_variables: {}, model_override: nil, stream: false, debug: false, max_turns: Float::INFINITY, execute_tools: true)
|
151
|
+
agent_tracker = OpenAISwarm::Agents::ChangeTracker.new(agent)
|
149
152
|
if stream
|
150
153
|
return run_and_stream(
|
151
154
|
agent: agent,
|
@@ -164,8 +167,11 @@ module OpenAISwarm
|
|
164
167
|
init_len = messages.length
|
165
168
|
|
166
169
|
while history.length - init_len < max_turns && active_agent
|
170
|
+
agent_tracker.update(active_agent)
|
171
|
+
history = OpenAISwarm::Util.latest_role_user_message(history) if agent_tracker.switch_agent_reset_message?
|
172
|
+
|
167
173
|
completion = get_chat_completion(
|
168
|
-
|
174
|
+
agent_tracker,
|
169
175
|
history,
|
170
176
|
context_variables,
|
171
177
|
model_override,
|
@@ -204,16 +210,21 @@ module OpenAISwarm
|
|
204
210
|
)
|
205
211
|
end
|
206
212
|
|
213
|
+
# TODO(Grayson): a lot of copied code here that will be refactored
|
207
214
|
def run_and_stream(agent:, messages:, context_variables: {}, model_override: nil, debug: false, max_turns: Float::INFINITY, execute_tools: true)
|
215
|
+
agent_tracker = OpenAISwarm::Agents::ChangeTracker.new(agent)
|
208
216
|
active_agent = agent
|
209
217
|
context_variables = context_variables.dup
|
210
218
|
history = messages.dup
|
211
219
|
init_len = messages.length
|
212
220
|
|
213
221
|
while history.length - init_len < max_turns && active_agent
|
222
|
+
agent_tracker.update(active_agent)
|
223
|
+
history = OpenAISwarm::Util.latest_role_user_message(history) if agent_tracker.switch_agent_reset_message?
|
224
|
+
|
214
225
|
message = OpenAISwarm::Util.message_template(agent.name)
|
215
226
|
completion = get_chat_completion(
|
216
|
-
|
227
|
+
agent_tracker,
|
217
228
|
history,
|
218
229
|
context_variables,
|
219
230
|
model_override,
|
@@ -1,5 +1,13 @@
|
|
1
1
|
module OpenAISwarm
|
2
2
|
module Util
|
3
|
+
class << self
|
4
|
+
def latest_role_user_message(history)
|
5
|
+
return history if history.empty?
|
6
|
+
filtered_messages = symbolize_keys_to_string(history.dup)
|
7
|
+
last_user_message = filtered_messages.reverse.find { |msg| msg['role'] == 'user' }
|
8
|
+
last_user_message ? [last_user_message] : history
|
9
|
+
end
|
10
|
+
end
|
3
11
|
def self.debug_print(debug, *args)
|
4
12
|
return unless debug
|
5
13
|
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
data/lib/ruby-openai-swarm.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'ruby-openai-swarm/version'
|
2
2
|
require 'ruby-openai-swarm/core_ext'
|
3
3
|
require 'ruby-openai-swarm/agent'
|
4
|
+
require 'ruby-openai-swarm/agents/change_tracker'
|
5
|
+
require 'ruby-openai-swarm/agents/strategy_options'
|
4
6
|
require 'ruby-openai-swarm/response'
|
5
7
|
require 'ruby-openai-swarm/result'
|
6
8
|
require 'ruby-openai-swarm/util'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-openai-swarm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grayson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|
@@ -106,6 +106,8 @@ files:
|
|
106
106
|
- examples/weather_agent/run.rb
|
107
107
|
- lib/ruby-openai-swarm.rb
|
108
108
|
- lib/ruby-openai-swarm/agent.rb
|
109
|
+
- lib/ruby-openai-swarm/agents/change_tracker.rb
|
110
|
+
- lib/ruby-openai-swarm/agents/strategy_options.rb
|
109
111
|
- lib/ruby-openai-swarm/configuration.rb
|
110
112
|
- lib/ruby-openai-swarm/core.rb
|
111
113
|
- lib/ruby-openai-swarm/core_ext.rb
|