ruby-openai-swarm 0.4.0.1 → 0.5.0

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: 455b72e5872a2f9e11dad1509769c5e3037cef23b3a622337fa419f9c8a2ab20
4
- data.tar.gz: 8f51f50b6ee3de651073783610d26f1394f2fbdb130aa8926b5184af921cfce0
3
+ metadata.gz: 922c68533aa6e9752cde8dd2fd2aaaca4d0d415acf7be59e41e5621c74cbb38d
4
+ data.tar.gz: 5472851d697e19fcc866a7898298a4fd67ed9486e9f30520e06584a15d640770
5
5
  SHA512:
6
- metadata.gz: fc109240efa4af18db7d9d2d60cf9e22fd55c36a9b9845617aa23a3ea912610001c98e0567cd34abd8dcf5e3f1cb86b85b0d474d356023912add3e2c730ad6cf
7
- data.tar.gz: 2d5d5740139edc78c5de1116c41e57397b3fce75f114f0459889c2f49c35846473a38fe35048977a5cecb79cb27d9af7d98c9fce48fa8926666165f6766f1dd3
6
+ metadata.gz: 3fa0c822a84dfd6c10220a28e5d266fbbcc0334d4bbd000333a889eb3483ed2c386706c4c1b72a62122789028ebe36124bd720bde97f561c8e6fda9136d666f6
7
+ data.tar.gz: 6653473c3e18ad66425437cd19583019826a1f827afd0b641d7993382fc5f4aee6377f9615cee50db4261f4d9818d32f33d28b57e24eda875056449b6487784e
@@ -20,7 +20,7 @@ jobs:
20
20
  - name: Run tests
21
21
  run: bundle exec rspec
22
22
  - name: Upload test results
23
- uses: actions/upload-artifact@v3
23
+ uses: actions/upload-artifact@v4
24
24
  if: failure()
25
25
  with:
26
26
  name: rspec-results
data/.gitignore CHANGED
@@ -27,7 +27,8 @@ build-iPhoneSimulator/
27
27
  .ruby-version
28
28
  .ruby-gemset
29
29
  /tmp
30
+ Gemfile*.lock
30
31
 
31
32
  # rspec failure tracking
32
33
  .rspec_status
33
- log/openai_swarm.log
34
+ log/openai_swarm.log
data/README.md CHANGED
@@ -16,7 +16,7 @@ A Ruby-based educational framework adapted from OpenAI’s [Swarm](https://githu
16
16
  - [Bundler](#bundler)
17
17
  - [Gem install](#gem-install)
18
18
  - [Logger](#logger)
19
- - [examples](#examples)
19
+ - [Quick start](#quick-start)
20
20
  - [Documentation](#documentation)
21
21
 
22
22
  ## quick show
@@ -86,7 +86,7 @@ def spanish_agent
86
86
  OpenAISwarm::Agent.new(
87
87
  name: "Spanish Agent",
88
88
  instructions: "You only speak Spanish.",
89
- model: "gpt-4o-mini"
89
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL']
90
90
  )
91
91
  end
92
92
 
@@ -98,7 +98,7 @@ transfer_to_spanish_agent = OpenAISwarm::FunctionDescriptor.new(
98
98
  english_agent = OpenAISwarm::Agent.new(
99
99
  name: "English Agent",
100
100
  instructions: "You only speak English.",
101
- model: "gpt-4o-mini",
101
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
102
102
  functions: [transfer_to_spanish_agent]
103
103
  )
104
104
 
@@ -127,9 +127,20 @@ OpenAISwarm.configure do |config|
127
127
  end
128
128
  ```
129
129
 
130
- # Examples
130
+ ## Quick Start
131
131
 
132
- Setting ACCESS_TOKEN for AI Providers in examples
132
+ ### Choose the default model name
133
+
134
+ `export SWARM_AGENT_DEFAULT_MODEL=gpt-4o-mini`
135
+
136
+ or
137
+
138
+ `export SWARM_AGENT_DEFAULT_MODEL=deepseek-chat`
139
+
140
+ DeepSeek V3 is 1/10 price of gpt-4o-mini, so try it!
141
+
142
+
143
+ ### Setting ACCESS_TOKEN for AI Providers in examples
133
144
 
134
145
  - For OpenRouter:
135
146
 
@@ -139,7 +150,11 @@ Setting ACCESS_TOKEN for AI Providers in examples
139
150
 
140
151
  `OPENAI_ACCESS_TOKEN=cxxxxx` or `export OPENAI_ACCESS_TOKEN=cxxxxx`
141
152
 
142
- Check out `/examples` for inspiration! Learn more about each one in its README.
153
+ - For DeepSeek:
154
+
155
+ `DEEPSEEK_ACCESS_TOKEN=cxxxxx` or `export DEEPSEEK_ACCESS_TOKEN=cxxxxx`
156
+
157
+ ### Check out `/examples` for inspiration! Learn more about each one in its README.
143
158
 
144
159
  - [X] [`basic`](examples/basic): Simple examples of fundamentals like setup, function calling, handoffs, and context variables
145
160
  - running: `ruby examples/basic/agent_handoff.rb`
@@ -150,7 +165,7 @@ Check out `/examples` for inspiration! Learn more about each one in its README.
150
165
  - [X] [`triage_agent`](examples/triage_agent): Simple example of setting up a basic triage step to hand off to the right agent
151
166
  - running: `ruby examples/triage_agent/main.rb`
152
167
  - [X] [`weather_agent`](examples/weather_agent): Simple example of function calling
153
- - running: `ruby examples/weather_agent/agents.rb`
168
+ - running: `ruby examples/weather_agent/run.rb`
154
169
  - [X] [`airline`](examples/airline): A multi-agent setup for handling different customer service requests in an airline context.
155
170
  - running: `DEBUG=1 ruby examples/airline/main.rb`
156
171
  - [ ] [`support_bot`](examples/support_bot): A customer service bot which includes a user interface agent and a help center agent with several tools
@@ -44,7 +44,7 @@ end
44
44
  # Define agents
45
45
  def triage_agent
46
46
  @triage_agent ||= OpenAISwarm::Agent.new(
47
- model: "gpt-4o-mini",
47
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
48
48
  name: "Triage Agent",
49
49
  instructions: method(:triage_instructions),
50
50
  functions: [
@@ -55,7 +55,7 @@ end
55
55
 
56
56
  def flight_modification
57
57
  @flight_modification ||= OpenAISwarm::Agent.new(
58
- model: "gpt-4o-mini",
58
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
59
59
  name: "Flight Modification Agent",
60
60
  instructions: <<~INSTRUCTIONS,
61
61
  You are a Flight Modification Agent for a customer service airlines company.
@@ -70,7 +70,7 @@ end
70
70
 
71
71
  def flight_cancel
72
72
  @flight_cancel ||= OpenAISwarm::Agent.new(
73
- model: "gpt-4o-mini",
73
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
74
74
  name: "Flight Cancel Traversal",
75
75
  instructions: STARTER_PROMPT + FLIGHT_CANCELLATION_POLICY,
76
76
  functions: [
@@ -85,7 +85,7 @@ end
85
85
 
86
86
  def flight_change
87
87
  @flight_change ||= OpenAISwarm::Agent.new(
88
- model: "gpt-4o-mini",
88
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
89
89
  name: "Flight Change Traversal",
90
90
  instructions: STARTER_PROMPT + FLIGHT_CHANGE_POLICY,
91
91
  functions: [
@@ -100,7 +100,7 @@ end
100
100
 
101
101
  def lost_baggage
102
102
  @lost_baggage ||= OpenAISwarm::Agent.new(
103
- model: "gpt-4o-mini",
103
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
104
104
  name: "Lost Baggage Traversal",
105
105
  instructions: STARTER_PROMPT + LOST_BAGGAGE_POLICY,
106
106
  functions: [
@@ -7,7 +7,7 @@ def spanish_agent
7
7
  OpenAISwarm::Agent.new(
8
8
  name: "Spanish Agent",
9
9
  instructions: "You only speak Spanish.",
10
- model: "gpt-4o-mini"
10
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL']
11
11
  )
12
12
  end
13
13
 
@@ -19,7 +19,7 @@ transfer_to_spanish_agent = OpenAISwarm::FunctionDescriptor.new(
19
19
  english_agent = OpenAISwarm::Agent.new(
20
20
  name: "English Agent",
21
21
  instructions: "You only speak English.",
22
- model: "gpt-4o-mini",
22
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
23
23
  functions: [transfer_to_spanish_agent]
24
24
  )
25
25
 
@@ -6,7 +6,7 @@ client = OpenAISwarm.new
6
6
  agent = OpenAISwarm::Agent.new(
7
7
  name: "Agent",
8
8
  instructions: "You are a helpful agent.",
9
- model: "gpt-4o-mini"
9
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL']
10
10
  )
11
11
  messages = [{"role": "user", "content": "Hi!"}]
12
12
  response = client.run(agent: agent, messages: messages)
@@ -24,7 +24,7 @@ function_instance = OpenAISwarm::FunctionDescriptor.new(
24
24
  agent = OpenAISwarm::Agent.new(
25
25
  name: "Agent",
26
26
  instructions: method(:instructions),
27
- model: "gpt-4o-mini",
27
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
28
28
  functions: [function_instance]
29
29
  )
30
30
 
@@ -27,7 +27,7 @@ get_weather_instance = OpenAISwarm::FunctionDescriptor.new(
27
27
  agent = OpenAISwarm::Agent.new(
28
28
  name: "Agent",
29
29
  instructions: "You are a helpful agent.",
30
- model: "gpt-4o-mini",
30
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
31
31
  functions: [
32
32
  get_weather_instance,
33
33
  get_news_instance
@@ -5,7 +5,7 @@ client = OpenAISwarm.new
5
5
  agent = OpenAISwarm::Agent.new(
6
6
  name: "Agent",
7
7
  instructions: "You are a helpful agent.",
8
- model: "gpt-4o-mini",
8
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
9
9
  )
10
10
 
11
11
  def pretty_print_messages(messages)
@@ -6,6 +6,11 @@ def env_debug
6
6
  end
7
7
 
8
8
  # TODO: refactor it
9
+ OpenAI.configure do |config|
10
+ config.access_token = ENV['DEEPSEEK_ACCESS_TOKEN']
11
+ config.uri_base = "https://api.deepseek.com"
12
+ end if ENV['DEEPSEEK_ACCESS_TOKEN']
13
+
9
14
  OpenAI.configure do |config|
10
15
  config.access_token = ENV['OPEN_ROUTER_ACCESS_TOKEN']
11
16
  config.uri_base = "https://openrouter.ai/api/v1"
@@ -0,0 +1,71 @@
1
+ require_relative "../bootstrap"
2
+
3
+ client = OpenAISwarm.new
4
+ model = ENV['SWARM_AGENT_DEFAULT_MODEL'] || "gpt-4o-mini"
5
+
6
+ memory = OpenAISwarm::Memory.new(memory_fields: ["language", "grade", "name", "sex"])
7
+ memory.function
8
+
9
+ def get_weather(location:)
10
+ puts "tool call: get_weather"
11
+ "{'temp':67, 'unit':'F'}"
12
+ end
13
+
14
+ def get_news(category:)
15
+ puts "tool call: get_news"
16
+ [
17
+ "Tech Company A Acquires Startup B",
18
+ "New AI Model Revolutionizes Industry",
19
+ "Breakthrough in Quantum Computing"
20
+ ].sample
21
+ end
22
+
23
+ get_news_instance = OpenAISwarm::FunctionDescriptor.new(
24
+ target_method: :get_news,
25
+ description: 'Get the latest news headlines. The category of news, e.g., world, business, sports.'
26
+ )
27
+
28
+ get_weather_instance = OpenAISwarm::FunctionDescriptor.new(
29
+ target_method: :get_weather,
30
+ description: 'Simulate fetching weather data'
31
+ )
32
+
33
+
34
+ system_prompt = "You are a helpful teaching assistant. Remember to save important information about the student using the core_memory_save function. Always greet the student by name if you know it."
35
+
36
+ chatbot_agent = OpenAISwarm::Agent.new(
37
+ name: "teaching_assistant",
38
+ instructions: system_prompt,
39
+ model: model,
40
+ functions: [
41
+ get_weather_instance,
42
+ get_news_instance
43
+ ],
44
+ memory: memory
45
+ )
46
+
47
+ messages1 = [
48
+ {
49
+ "role": "user",
50
+ "content": "Hi, I'm John. I speak Chinese and I'm in Senior Year. Get the current weather in a given location. Location MUST be a city."
51
+ }
52
+ ]
53
+
54
+ puts "first call, set memory"
55
+ puts "messages: #{messages1}"
56
+
57
+ response1 = client.run(agent: chatbot_agent, messages: messages1, debug: env_debug)
58
+ puts "memory data: #{memory.entity_store.data}"
59
+ puts response1.messages.last['content']
60
+
61
+ puts ""
62
+ messages2 = [
63
+ {"role": "user", "content": "what is my name"},
64
+ ]
65
+ puts "2nd call, get memory"
66
+ puts "memory data: #{memory.entity_store.data}"
67
+ puts "messages: #{messages2}"
68
+
69
+ response2 = client.run(agent: chatbot_agent, messages: messages2, debug: env_debug)
70
+
71
+ puts response2.messages.last['content']
@@ -33,7 +33,7 @@ def weather_agent
33
33
  OpenAISwarm::Agent.new(
34
34
  name: "Weather Agent",
35
35
  instructions: "You are a helpful agent.",
36
- model: "gpt-4o-mini",
36
+ model: ENV['SWARM_AGENT_DEFAULT_MODEL'],
37
37
  functions: [
38
38
  function_instance_send_email,
39
39
  function_instance_get_weather
@@ -7,7 +7,8 @@ module OpenAISwarm
7
7
  :noisy_tool_calls,
8
8
  :temperature,
9
9
  :current_tool_name,
10
- :resource
10
+ :resource,
11
+ :memory
11
12
  # These attributes can be read and written externally. They include:
12
13
  # - name: The name of the agent.
13
14
  # - model: The model used, e.g., "gpt-4".
@@ -27,7 +28,8 @@ module OpenAISwarm
27
28
  resource: nil,
28
29
  noisy_tool_calls: [],
29
30
  strategy: {},
30
- current_tool_name: nil
31
+ current_tool_name: nil,
32
+ memory: nil
31
33
  )
32
34
  @name = name
33
35
  @model = model
@@ -40,6 +42,13 @@ module OpenAISwarm
40
42
  @noisy_tool_calls = noisy_tool_calls
41
43
  @strategy = Agents::StrategyOptions.new(strategy)
42
44
  @current_tool_name = current_tool_name.nil? ? nil : current_tool_name.to_s
45
+ @memory = memory
46
+ end
47
+
48
+ def functions
49
+ return @functions if memory&.function.nil?
50
+
51
+ @functions.push(memory.function)
43
52
  end
44
53
  end
45
54
  end
@@ -1,4 +1,5 @@
1
1
  require 'ruby/openai'
2
+ require 'ostruct'
2
3
  begin
3
4
  require 'pry'
4
5
  rescue LoadError
@@ -14,11 +15,28 @@ module OpenAISwarm
14
15
  @logger = OpenAISwarm::Logger.instance.logger
15
16
  end
16
17
 
18
+ # TODO(Grayson)
19
+ # def create_agent(name:, model:, instructions:, **options)
20
+ # memory = Memory.new(@memory_fields)
21
+ # Agent.new(
22
+ # name: name,
23
+ # model: model,
24
+ # instructions: instructions,
25
+ # memory: memory,
26
+ # functions: functions,
27
+ # **options
28
+ # )
29
+ # end
30
+
17
31
  def get_chat_completion(agent_tracker, history, context_variables, model_override, stream, debug)
18
32
  agent = agent_tracker.current_agent
19
33
  context_variables = context_variables.dup
20
34
  instructions = agent.instructions.respond_to?(:call) ? agent.instructions.call(context_variables) : agent.instructions
21
- messages = [{ role: 'system', content: instructions }] + history
35
+
36
+ # Build a message history, including memories
37
+ messages = [{ role: 'system', content: instructions }]
38
+ messages << { role: 'system', content: agent.memory.prompt_content } unless agent&.memory&.prompt_content.nil?
39
+ messages += history
22
40
 
23
41
  # Util.debug_print(debug, "Getting chat completion for...:", messages)
24
42
 
@@ -65,9 +83,10 @@ module OpenAISwarm
65
83
 
66
84
  Util.debug_print(debug, "API Response:", response)
67
85
  response
68
- rescue OpenAI::Error => e
69
- log_message(:error, "OpenAI API Error: #{e.message}")
70
- Util.debug_print(true, "OpenAI API Error:", e.message)
86
+ rescue OpenAI::Error, Faraday::BadRequestError => e
87
+ error_message = (e.response || {}).dig(:body) || e.inspect
88
+ log_message(:error, "OpenAI API Error: #{error_message}")
89
+ Util.debug_print(true, "OpenAI API Error:", error_message)
71
90
  raise
72
91
  end
73
92
 
@@ -181,11 +200,11 @@ module OpenAISwarm
181
200
  debug
182
201
  )
183
202
 
184
- message = completion.dig('choices', 0, 'message')
203
+ message = completion.dig('choices', 0, 'message') || {}
185
204
  Util.debug_print(debug, "Received completion:", message)
186
205
  log_message(:info, "Received completion:", message)
187
206
 
188
- message['sender'] = active_agent.name
207
+ message['sender'] = active_agent&.name
189
208
  history << message
190
209
 
191
210
  if !message['tool_calls'] || !execute_tools
@@ -0,0 +1,27 @@
1
+ module OpenAISwarm
2
+ module Memories
3
+ class CoreMemoryFunction
4
+ def self.definition(memory_fields = [])
5
+ properties = {}
6
+
7
+ memory_fields.each do |memory_field|
8
+ field = memory_field.field
9
+ description = "The #{field} to remember." + memory_field&.tool_call_description.to_s
10
+ properties[field] = { type: "string", description: description }
11
+ end
12
+
13
+ {
14
+ type: "function",
15
+ function: {
16
+ name: "core_memory_save",
17
+ description: "Save important information about you, the agent or the human you are chatting with.",
18
+ parameters: {
19
+ type: "object",
20
+ properties: properties,
21
+ }
22
+ }
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,54 @@
1
+ module OpenAISwarm
2
+ module Memories
3
+ class EntityStore
4
+ attr_accessor :entity_store,
5
+ :data
6
+
7
+ def initialize(entity_store = nil)
8
+ @entity_store = entity_store
9
+ @data = entity_store&.data || {}
10
+ end
11
+
12
+ def entity_store_save
13
+ return unless entity_store.respond_to?(:update)
14
+
15
+ entity_store.update(data: data)
16
+ end
17
+
18
+ def add_entities(entities)
19
+ entities.each { |key, value| @data[key.to_sym] = value }
20
+ entity_store_save
21
+ end
22
+
23
+ def memories
24
+ data&.to_json
25
+ end
26
+
27
+ # def add(key, value)
28
+ # @data[key] = value
29
+ # entity_store_save
30
+ # @data
31
+ # end
32
+
33
+ # def get(key)
34
+ # @data[key]
35
+ # end
36
+
37
+ # def exists?(key)
38
+ # @data.key?(key)
39
+ # end
40
+
41
+ # def remove(key)
42
+ # @data.delete(key)
43
+ # end
44
+
45
+ # def clear
46
+ # @data = {}
47
+ # end
48
+
49
+ # def all
50
+ # @data
51
+ # end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ module OpenAISwarm
2
+ module Memories
3
+ class Field
4
+ attr_accessor :field,
5
+ :tool_call_description
6
+
7
+ VALID_MEMORY_FIELDS = [:field, :tool_call_description].freeze
8
+
9
+ def initialize(memory_field)
10
+ memory_field.is_a?(Hash) ? parse_hash(memory_field) : parse_string(memory_field)
11
+ end
12
+
13
+ def parse_hash(memory_field)
14
+ validate_memory_field!(memory_field)
15
+
16
+ @field = memory_field[:field]
17
+ @tool_call_description = memory_field[:tool_call_description]
18
+ end
19
+
20
+ def parse_string(memory_field)
21
+ @field = memory_field
22
+ end
23
+
24
+ private
25
+
26
+ def validate_memory_field!(memory_field)
27
+ unless memory_field.include?(:field)
28
+ raise ArgumentError, "memory_field must include :field"
29
+ end
30
+
31
+ invalid_fields = memory_field.keys - VALID_MEMORY_FIELDS
32
+
33
+ unless invalid_fields.empty?
34
+ raise ArgumentError, "Invalid memory fields: #{invalid_fields.join(', ')}. Valid fields are: #{VALID_MEMORY_FIELDS.join(', ')}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ module OpenAISwarm
2
+ class Memory
3
+ attr_reader :memories,
4
+ :entity_store
5
+
6
+ def initialize(memory_fields: [], entity_store: nil)
7
+ @memory_fields = normalize_memory_fields(memory_fields)
8
+ @entity_store = Memories::EntityStore.new(entity_store)
9
+ end
10
+
11
+ def normalize_memory_fields(memory_fields)
12
+ return [] if memory_fields.empty?
13
+
14
+ memory_fields.map { |memory_field| Memories::Field.new(memory_field) }
15
+ end
16
+
17
+ def core_memory_save(entities)
18
+ entity_store.add_entities(entities)
19
+ end
20
+
21
+ def prompt_content
22
+ return nil if get_memories_data.nil?
23
+
24
+ fields = @memory_fields.map(&:field).join(", ")
25
+ "You have a section of your context called [MEMORY] " \
26
+ "that contains the following information: #{fields}. " \
27
+ "Here are the relevant details: [MEMORY]\n" \
28
+ "#{get_memories_data}"
29
+ end
30
+
31
+ def function
32
+ return nil if @memory_fields.empty?
33
+
34
+ OpenAISwarm::FunctionDescriptor.new(
35
+ target_method: method(:core_memory_save),
36
+ description: core_memory_save_metadata[:function][:description],
37
+ parameters: core_memory_save_metadata[:function][:parameters]
38
+ )
39
+ end
40
+
41
+ def core_memory_save_metadata
42
+ @core_memory_save_metadata ||= Memories::CoreMemoryFunction.definition(@memory_fields)
43
+ end
44
+
45
+ def get_memories_data
46
+ entity_store&.memories
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module OpenAISwarm
2
- VERSION = "0.4.0.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -11,6 +11,11 @@ require 'ruby-openai-swarm/function_descriptor'
11
11
  require 'ruby-openai-swarm/repl'
12
12
  require 'ruby-openai-swarm/configuration'
13
13
  require 'ruby-openai-swarm/logger'
14
+ require 'ruby-openai-swarm/memory'
15
+ require 'ruby-openai-swarm/memories/entity_store'
16
+ require 'ruby-openai-swarm/memories/core_memory_function'
17
+ require 'ruby-openai-swarm/memories/field'
18
+
14
19
 
15
20
  module OpenAISwarm
16
21
  class Error < StandardError;
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.require_paths = ["lib"]
24
24
  spec.add_dependency "ruby-openai", "~> 7.3"
25
+ spec.add_dependency "ostruct"
25
26
  spec.add_development_dependency "rspec", "~> 3.0"
26
27
  spec.add_development_dependency "rake", "~> 13.0"
27
28
  spec.add_development_dependency "pry"
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.0.1
4
+ version: 0.5.0
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-26 00:00:00.000000000 Z
11
+ date: 2025-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-openai
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '7.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ostruct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,7 +92,6 @@ files:
78
92
  - ".gitignore"
79
93
  - ".rspec"
80
94
  - Gemfile
81
- - Gemfile.lock
82
95
  - README.md
83
96
  - Rakefile
84
97
  - assets/logo-swarm.png
@@ -98,6 +111,7 @@ files:
98
111
  - examples/basic/function_calling.rb
99
112
  - examples/basic/simple_loop_no_helpers.rb
100
113
  - examples/bootstrap.rb
114
+ - examples/memory/memory_save.rb
101
115
  - examples/triage_agent/README.md
102
116
  - examples/triage_agent/agents.rb
103
117
  - examples/triage_agent/main.rb
@@ -113,6 +127,10 @@ files:
113
127
  - lib/ruby-openai-swarm/core_ext.rb
114
128
  - lib/ruby-openai-swarm/function_descriptor.rb
115
129
  - lib/ruby-openai-swarm/logger.rb
130
+ - lib/ruby-openai-swarm/memories/core_memory_function.rb
131
+ - lib/ruby-openai-swarm/memories/entity_store.rb
132
+ - lib/ruby-openai-swarm/memories/field.rb
133
+ - lib/ruby-openai-swarm/memory.rb
116
134
  - lib/ruby-openai-swarm/repl.rb
117
135
  - lib/ruby-openai-swarm/response.rb
118
136
  - lib/ruby-openai-swarm/result.rb
@@ -141,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
159
  - !ruby/object:Gem::Version
142
160
  version: '0'
143
161
  requirements: []
144
- rubygems_version: 3.1.4
162
+ rubygems_version: 3.5.3
145
163
  signing_key:
146
164
  specification_version: 4
147
165
  summary: A Ruby implementation of OpenAI function calling swarm
data/Gemfile.lock DELETED
@@ -1,56 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ruby-openai-swarm (0.4.0.1)
5
- ruby-openai (~> 7.3)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- base64 (0.2.0)
11
- coderay (1.1.3)
12
- diff-lcs (1.5.1)
13
- event_stream_parser (1.0.0)
14
- faraday (2.8.1)
15
- base64
16
- faraday-net_http (>= 2.0, < 3.1)
17
- ruby2_keywords (>= 0.0.4)
18
- faraday-multipart (1.1.0)
19
- multipart-post (~> 2.0)
20
- faraday-net_http (3.0.2)
21
- method_source (1.1.0)
22
- multipart-post (2.4.1)
23
- pry (0.14.2)
24
- coderay (~> 1.1)
25
- method_source (~> 1.0)
26
- rake (13.2.1)
27
- rspec (3.13.0)
28
- rspec-core (~> 3.13.0)
29
- rspec-expectations (~> 3.13.0)
30
- rspec-mocks (~> 3.13.0)
31
- rspec-core (3.13.2)
32
- rspec-support (~> 3.13.0)
33
- rspec-expectations (3.13.3)
34
- diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.13.0)
36
- rspec-mocks (3.13.2)
37
- diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.13.0)
39
- rspec-support (3.13.1)
40
- ruby-openai (7.3.1)
41
- event_stream_parser (>= 0.3.0, < 2.0.0)
42
- faraday (>= 1)
43
- faraday-multipart (>= 1)
44
- ruby2_keywords (0.0.5)
45
-
46
- PLATFORMS
47
- ruby
48
-
49
- DEPENDENCIES
50
- pry
51
- rake (~> 13.0)
52
- rspec (~> 3.0)
53
- ruby-openai-swarm!
54
-
55
- BUNDLED WITH
56
- 2.1.4