diff --git a/lib/langchain/assistants/assistant.rb b/lib/langchain/assistants/assistant.rb index 7b1d76425..9f689a688 100644 --- a/lib/langchain/assistants/assistant.rb +++ b/lib/langchain/assistants/assistant.rb @@ -27,6 +27,7 @@ class Assistant # @params add_message_callback [Proc] A callback function (Proc or lambda) that is called when any message is added to the conversation def initialize( llm:, + llm_adapter: nil, tools: [], instructions: nil, tool_choice: "auto", @@ -39,7 +40,7 @@ def initialize( end @llm = llm - @llm_adapter = LLM::Adapter.build(llm) + @llm_adapter = llm_adapter || LLM::Adapter.build(llm) # TODO: Validate that it is, indeed, a Proc or lambda if !add_message_callback.nil? && !add_message_callback.respond_to?(:call) diff --git a/lib/langchain/assistants/llm/adapters/_base.rb b/lib/langchain/assistants/llm/adapters/_base.rb index 4cdcad18c..8b7d3f551 100644 --- a/lib/langchain/assistants/llm/adapters/_base.rb +++ b/lib/langchain/assistants/llm/adapters/_base.rb @@ -20,7 +20,11 @@ def tool_role end def support_system_message? - raise NotImplementedError, "Subclasses must implement set_instructions" + raise NotImplementedError, "Subclasses must implement support_system_message?" + end + + def allowed_tool_choices + raise NotImplementedError, "Subclasses must implement allowed_tool_choices" end end end diff --git a/spec/langchain/assistants/assistant_spec.rb b/spec/langchain/assistants/assistant_spec.rb index ac4595ea2..8bca60f7c 100644 --- a/spec/langchain/assistants/assistant_spec.rb +++ b/spec/langchain/assistants/assistant_spec.rb @@ -1360,4 +1360,72 @@ end end end + + context "when llm is custom" do + let(:llm) { Langchain::LLM::Base.new } + let(:llm_adapter_class) do + Class.new(Langchain::Assistant::LLM::Adapters::Base) do + def allowed_tool_choices + ["auto"] + end + + def available_tool_names(tools) + [] + end + + def support_system_message? + true + end + + def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil) + message_class = Class.new(Langchain::Messages::Base) do + def initialize(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil) + @role = role + @content = content.to_s + @image_url = image_url + @tool_calls = tool_calls + @tool_call_id = tool_call_id + end + end + + message_class.new( + role: role, + content: content, + image_url: image_url, + tool_calls: tool_calls, + tool_call_id: tool_call_id + ) + end + end + end + let(:llm_adapter) { llm_adapter_class.new } + let(:calculator) { Langchain::Tool::Calculator.new } + let(:instructions) { "You are an expert assistant" } + + subject { + described_class.new( + llm: llm, + llm_adapter: llm_adapter, + tools: [calculator], + instructions: instructions + ) + } + + describe ".new" do + it "initiates an assistant without error" do + expect { subject }.not_to raise_error + end + end + + describe "#messages" do + it "returns list of messages" do + expect(subject.messages).to contain_exactly( + an_object_having_attributes( + role: "system", + content: "You are an expert assistant" + ) + ) + end + end + end end