Skip to content

Commit

Permalink
Add Assistant#add_messages() method and fix Assistant#messages= m…
Browse files Browse the repository at this point in the history
…ethod (#731)

* Add Assistant#add_messages() method and fix Assistant#messages= method

* Bump ruby-openai gem

* fix linter

* method annotation
  • Loading branch information
andreibondarev authored Aug 22, 2024
1 parent ecb7826 commit 9f0941d
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ GEM
ruby-next-parser (3.2.2.0)
parser (>= 3.0.3.1)
ruby-ole (1.2.13.1)
ruby-openai (6.4.0)
ruby-openai (7.1.0)
event_stream_parser (>= 0.3.0, < 2.0.0)
faraday (>= 1)
faraday-multipart (>= 1)
Expand Down Expand Up @@ -479,7 +479,7 @@ DEPENDENCIES
roo-xls (~> 1.2.0)
rspec (~> 3.0)
rubocop
ruby-openai (~> 6.4.0)
ruby-openai (~> 7.1.0)
safe_ruby (~> 1.0.4)
sequel (~> 5.68.0)
standard (>= 1.35.1)
Expand Down
2 changes: 1 addition & 1 deletion langchain.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "qdrant-ruby", "~> 0.9.4"
spec.add_development_dependency "roo", "~> 2.10.0"
spec.add_development_dependency "roo-xls", "~> 1.2.0"
spec.add_development_dependency "ruby-openai", "~> 6.4.0"
spec.add_development_dependency "ruby-openai", "~> 7.1.0"
spec.add_development_dependency "safe_ruby", "~> 1.0.4"
spec.add_development_dependency "sequel", "~> 5.68.0"
spec.add_development_dependency "weaviate-ruby", "~> 0.8.10"
Expand Down
21 changes: 20 additions & 1 deletion lib/langchain/assistants/assistant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Langchain
# )
class Assistant
extend Forwardable
def_delegators :thread, :messages, :messages=
def_delegators :thread, :messages

attr_reader :llm, :thread, :instructions, :state
attr_reader :total_prompt_tokens, :total_completion_tokens, :total_tokens
Expand Down Expand Up @@ -69,6 +69,25 @@ def add_message(content: nil, role: "user", tool_calls: [], tool_call_id: nil)
messages
end

# Set multiple messages to the thread
#
# @param messages [Array<Hash>] The messages to set
# @return [Array<Langchain::Message>] The messages in the thread
def messages=(messages)
clear_thread!
add_messages(messages: messages)
end

# Add multiple messages to the thread
#
# @param messages [Array<Hash>] The messages to add
# @return [Array<Langchain::Message>] The messages in the thread
def add_messages(messages:)
messages.each do |message_hash|
add_message(**message_hash.slice(:content, :role, :tool_calls, :tool_call_id))
end
end

# Run the assistant
#
# @param auto_tool_execution [Boolean] Whether or not to automatically run tools
Expand Down
91 changes: 91 additions & 0 deletions spec/langchain/assistants/assistant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,97 @@
end
end
end

describe "#add_messages" do
let(:messages) do
[
{role: "user", content: "Hello"},
{role: "assistant", content: "Hi there!"},
{role: "user", content: "How are you?"}
]
end

it "adds multiple messages to the thread" do
expect { subject.add_messages(messages: messages) }
.to change { subject.messages.count }.by(3)
end

it "adds messages with correct roles and content" do
subject.add_messages(messages: messages)

expect(subject.messages[-3].role).to eq("user")
expect(subject.messages[-3].content).to eq("Hello")

expect(subject.messages[-2].role).to eq("assistant")
expect(subject.messages[-2].content).to eq("Hi there!")

expect(subject.messages[-1].role).to eq("user")
expect(subject.messages[-1].content).to eq("How are you?")
end

it "handles messages with tool_calls" do
messages_with_tool_calls = [
{
role: "assistant",
tool_calls: [
{
"id" => "call_123",
"type" => "function",
"function" => {
"name" => "get_weather",
"arguments" => "{\"location\":\"New York\"}"
}
}
]
}
]

subject.add_messages(messages: messages_with_tool_calls)

expect(subject.messages.last.role).to eq("assistant")
expect(subject.messages.last.content).to be_empty
expect(subject.messages.last.tool_calls).to eq(messages_with_tool_calls.first[:tool_calls])
end

it "handles messages with tool_call_id" do
messages_with_tool_call_id = [
{role: "tool", content: "Sunny, 25°C", tool_call_id: "call_123"}
]

subject.add_messages(messages: messages_with_tool_call_id)

expect(subject.messages.last.role).to eq("tool")
expect(subject.messages.last.content).to eq("Sunny, 25°C")
expect(subject.messages.last.tool_call_id).to eq("call_123")
end

it "maintains the order of messages" do
subject.add_messages(messages: messages)

expect(subject.messages[-3..].map(&:role)).to eq(["user", "assistant", "user"])
expect(subject.messages[-3..].map(&:content)).to eq(["Hello", "Hi there!", "How are you?"])
end

context "when messages array is empty" do
it "doesn't change the thread" do
expect { subject.add_messages(messages: []) }
.not_to change { subject.messages.count }
end
end

context "when a message has an invalid role" do
let(:invalid_messages) do
[
{role: "invalid_role", content: "This shouldn't work"}
]
end

it "raises an ArgumentError" do
expect { subject.add_messages(messages: invalid_messages) }
.to raise_error(ArgumentError, /Role must be one of system, assistant, user, tool/)
end
end
end
end

context "when llm is GoogleGemini" do
Expand Down

0 comments on commit 9f0941d

Please sign in to comment.