langchainrb 0.17.1 → 0.19.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +7 -2
  4. data/lib/langchain/{assistants → assistant}/llm/adapter.rb +1 -1
  5. data/lib/langchain/assistant/llm/adapters/anthropic.rb +105 -0
  6. data/lib/langchain/assistant/llm/adapters/base.rb +63 -0
  7. data/lib/langchain/{assistants → assistant}/llm/adapters/google_gemini.rb +43 -3
  8. data/lib/langchain/{assistants → assistant}/llm/adapters/mistral_ai.rb +39 -2
  9. data/lib/langchain/assistant/llm/adapters/ollama.rb +94 -0
  10. data/lib/langchain/{assistants → assistant}/llm/adapters/openai.rb +38 -2
  11. data/lib/langchain/assistant/messages/anthropic_message.rb +83 -0
  12. data/lib/langchain/assistant/messages/base.rb +56 -0
  13. data/lib/langchain/assistant/messages/google_gemini_message.rb +92 -0
  14. data/lib/langchain/assistant/messages/mistral_ai_message.rb +143 -0
  15. data/lib/langchain/assistant/messages/ollama_message.rb +76 -0
  16. data/lib/langchain/assistant/messages/openai_message.rb +105 -0
  17. data/lib/langchain/{assistants/assistant.rb → assistant.rb} +26 -48
  18. data/lib/langchain/llm/ai21.rb +1 -1
  19. data/lib/langchain/llm/anthropic.rb +64 -9
  20. data/lib/langchain/llm/aws_bedrock.rb +12 -13
  21. data/lib/langchain/llm/azure.rb +2 -2
  22. data/lib/langchain/llm/base.rb +1 -1
  23. data/lib/langchain/llm/cohere.rb +8 -8
  24. data/lib/langchain/llm/google_gemini.rb +5 -6
  25. data/lib/langchain/llm/google_vertex_ai.rb +6 -5
  26. data/lib/langchain/llm/hugging_face.rb +5 -5
  27. data/lib/langchain/llm/mistral_ai.rb +4 -4
  28. data/lib/langchain/llm/ollama.rb +7 -8
  29. data/lib/langchain/llm/openai.rb +8 -7
  30. data/lib/langchain/llm/parameters/chat.rb +1 -0
  31. data/lib/langchain/llm/replicate.rb +8 -16
  32. data/lib/langchain/tool_definition.rb +7 -0
  33. data/lib/langchain/version.rb +1 -1
  34. data/lib/langchain.rb +1 -14
  35. metadata +16 -16
  36. data/lib/langchain/assistants/llm/adapters/_base.rb +0 -21
  37. data/lib/langchain/assistants/llm/adapters/anthropic.rb +0 -62
  38. data/lib/langchain/assistants/llm/adapters/ollama.rb +0 -57
  39. data/lib/langchain/assistants/messages/anthropic_message.rb +0 -75
  40. data/lib/langchain/assistants/messages/base.rb +0 -54
  41. data/lib/langchain/assistants/messages/google_gemini_message.rb +0 -90
  42. data/lib/langchain/assistants/messages/mistral_ai_message.rb +0 -96
  43. data/lib/langchain/assistants/messages/ollama_message.rb +0 -74
  44. data/lib/langchain/assistants/messages/openai_message.rb +0 -103
@@ -5,16 +5,16 @@ module Langchain::LLM
5
5
  # Wrapper around Anthropic APIs.
6
6
  #
7
7
  # Gem requirements:
8
- # gem "anthropic", "~> 0.3.0"
8
+ # gem "anthropic", "~> 0.3.2"
9
9
  #
10
10
  # Usage:
11
- # anthropic = Langchain::LLM::Anthropic.new(api_key: ENV["ANTHROPIC_API_KEY"])
11
+ # llm = Langchain::LLM::Anthropic.new(api_key: ENV["ANTHROPIC_API_KEY"])
12
12
  #
13
13
  class Anthropic < Base
14
14
  DEFAULTS = {
15
15
  temperature: 0.0,
16
- completion_model_name: "claude-2.1",
17
- chat_completion_model_name: "claude-3-5-sonnet-20240620",
16
+ completion_model: "claude-2.1",
17
+ chat_model: "claude-3-5-sonnet-20240620",
18
18
  max_tokens_to_sample: 256
19
19
  }.freeze
20
20
 
@@ -22,7 +22,7 @@ module Langchain::LLM
22
22
  #
23
23
  # @param api_key [String] The API key to use
24
24
  # @param llm_options [Hash] Options to pass to the Anthropic client
25
- # @param default_options [Hash] Default options to use on every call to LLM, e.g.: { temperature:, completion_model_name:, chat_completion_model_name:, max_tokens_to_sample: }
25
+ # @param default_options [Hash] Default options to use on every call to LLM, e.g.: { temperature:, completion_model:, chat_model:, max_tokens_to_sample: }
26
26
  # @return [Langchain::LLM::Anthropic] Langchain::LLM::Anthropic instance
27
27
  def initialize(api_key:, llm_options: {}, default_options: {})
28
28
  depends_on "anthropic"
@@ -30,7 +30,7 @@ module Langchain::LLM
30
30
  @client = ::Anthropic::Client.new(access_token: api_key, **llm_options)
31
31
  @defaults = DEFAULTS.merge(default_options)
32
32
  chat_parameters.update(
33
- model: {default: @defaults[:chat_completion_model_name]},
33
+ model: {default: @defaults[:chat_model]},
34
34
  temperature: {default: @defaults[:temperature]},
35
35
  max_tokens: {default: @defaults[:max_tokens_to_sample]},
36
36
  metadata: {},
@@ -54,7 +54,7 @@ module Langchain::LLM
54
54
  # @return [Langchain::LLM::AnthropicResponse] The completion
55
55
  def complete(
56
56
  prompt:,
57
- model: @defaults[:completion_model_name],
57
+ model: @defaults[:completion_model],
58
58
  max_tokens_to_sample: @defaults[:max_tokens_to_sample],
59
59
  stop_sequences: nil,
60
60
  temperature: @defaults[:temperature],
@@ -100,7 +100,7 @@ module Langchain::LLM
100
100
  # @option params [Integer] :top_k Only sample from the top K options for each subsequent token
101
101
  # @option params [Float] :top_p Use nucleus sampling.
102
102
  # @return [Langchain::LLM::AnthropicResponse] The chat completion
103
- def chat(params = {})
103
+ def chat(params = {}, &block)
104
104
  set_extra_headers! if params[:tools]
105
105
 
106
106
  parameters = chat_parameters.to_params(params)
@@ -109,9 +109,19 @@ module Langchain::LLM
109
109
  raise ArgumentError.new("model argument is required") if parameters[:model].empty?
110
110
  raise ArgumentError.new("max_tokens argument is required") if parameters[:max_tokens].nil?
111
111
 
112
- binding.pry
112
+ if block
113
+ @response_chunks = []
114
+ parameters[:stream] = proc do |chunk|
115
+ @response_chunks << chunk
116
+ yield chunk
117
+ end
118
+ end
119
+
113
120
  response = client.messages(parameters: parameters)
114
121
 
122
+ response = response_from_chunks if block
123
+ reset_response_chunks
124
+
115
125
  Langchain::LLM::AnthropicResponse.new(response)
116
126
  end
117
127
 
@@ -124,8 +134,53 @@ module Langchain::LLM
124
134
  response
125
135
  end
126
136
 
137
+ def response_from_chunks
138
+ grouped_chunks = @response_chunks.group_by { |chunk| chunk["index"] }.except(nil)
139
+
140
+ usage = @response_chunks.find { |chunk| chunk["type"] == "message_delta" }&.dig("usage")
141
+ stop_reason = @response_chunks.find { |chunk| chunk["type"] == "message_delta" }&.dig("delta", "stop_reason")
142
+
143
+ content = grouped_chunks.map do |_index, chunks|
144
+ text = chunks.map { |chunk| chunk.dig("delta", "text") }.join
145
+ if !text.nil? && !text.empty?
146
+ {"type" => "text", "text" => text}
147
+ else
148
+ tool_calls_from_choice_chunks(chunks)
149
+ end
150
+ end.flatten
151
+
152
+ @response_chunks.first&.slice("id", "object", "created", "model")
153
+ &.merge!(
154
+ {
155
+ "content" => content,
156
+ "usage" => usage,
157
+ "role" => "assistant",
158
+ "stop_reason" => stop_reason
159
+ }
160
+ )
161
+ end
162
+
163
+ def tool_calls_from_choice_chunks(chunks)
164
+ return unless (first_block = chunks.find { |chunk| chunk.dig("content_block", "type") == "tool_use" })
165
+
166
+ chunks.group_by { |chunk| chunk["index"] }.map do |index, chunks|
167
+ input = chunks.select { |chunk| chunk.dig("delta", "partial_json") }
168
+ .map! { |chunk| chunk.dig("delta", "partial_json") }.join
169
+ {
170
+ "id" => first_block.dig("content_block", "id"),
171
+ "type" => "tool_use",
172
+ "name" => first_block.dig("content_block", "name"),
173
+ "input" => JSON.parse(input).transform_keys(&:to_sym)
174
+ }
175
+ end.compact
176
+ end
177
+
127
178
  private
128
179
 
180
+ def reset_response_chunks
181
+ @response_chunks = []
182
+ end
183
+
129
184
  def set_extra_headers!
130
185
  ::Anthropic.configuration.extra_headers = {"anthropic-beta": "tools-2024-05-16"}
131
186
  end
@@ -7,12 +7,13 @@ module Langchain::LLM
7
7
  # gem 'aws-sdk-bedrockruntime', '~> 1.1'
8
8
  #
9
9
  # Usage:
10
- # bedrock = Langchain::LLM::AwsBedrock.new(llm_options: {})
10
+ # llm = Langchain::LLM::AwsBedrock.new(llm_options: {})
11
11
  #
12
12
  class AwsBedrock < Base
13
13
  DEFAULTS = {
14
- completion_model_name: "anthropic.claude-v2",
15
- embedding_model_name: "amazon.titan-embed-text-v1",
14
+ chat_model: "anthropic.claude-v2",
15
+ completion_model: "anthropic.claude-v2",
16
+ embedding_model: "amazon.titan-embed-text-v1",
16
17
  max_tokens_to_sample: 300,
17
18
  temperature: 1,
18
19
  top_k: 250,
@@ -52,16 +53,14 @@ module Langchain::LLM
52
53
  SUPPORTED_CHAT_COMPLETION_PROVIDERS = %i[anthropic].freeze
53
54
  SUPPORTED_EMBEDDING_PROVIDERS = %i[amazon cohere].freeze
54
55
 
55
- def initialize(completion_model: DEFAULTS[:completion_model_name], embedding_model: DEFAULTS[:embedding_model_name], aws_client_options: {}, default_options: {})
56
+ def initialize(aws_client_options: {}, default_options: {})
56
57
  depends_on "aws-sdk-bedrockruntime", req: "aws-sdk-bedrockruntime"
57
58
 
58
59
  @client = ::Aws::BedrockRuntime::Client.new(**aws_client_options)
59
60
  @defaults = DEFAULTS.merge(default_options)
60
- .merge(completion_model_name: completion_model)
61
- .merge(embedding_model_name: embedding_model)
62
61
 
63
62
  chat_parameters.update(
64
- model: {default: @defaults[:chat_completion_model_name]},
63
+ model: {default: @defaults[:chat_model]},
65
64
  temperature: {},
66
65
  max_tokens: {default: @defaults[:max_tokens_to_sample]},
67
66
  metadata: {},
@@ -85,7 +84,7 @@ module Langchain::LLM
85
84
  parameters = compose_embedding_parameters params.merge(text:)
86
85
 
87
86
  response = client.invoke_model({
88
- model_id: @defaults[:embedding_model_name],
87
+ model_id: @defaults[:embedding_model],
89
88
  body: parameters.to_json,
90
89
  content_type: "application/json",
91
90
  accept: "application/json"
@@ -104,14 +103,14 @@ module Langchain::LLM
104
103
  def complete(prompt:, **params)
105
104
  raise "Completion provider #{completion_provider} is not supported." unless SUPPORTED_COMPLETION_PROVIDERS.include?(completion_provider)
106
105
 
107
- raise "Model #{@defaults[:completion_model_name]} only supports #chat." if @defaults[:completion_model_name].include?("claude-3")
106
+ raise "Model #{@defaults[:completion_model]} only supports #chat." if @defaults[:completion_model].include?("claude-3")
108
107
 
109
108
  parameters = compose_parameters params
110
109
 
111
110
  parameters[:prompt] = wrap_prompt prompt
112
111
 
113
112
  response = client.invoke_model({
114
- model_id: @defaults[:completion_model_name],
113
+ model_id: @defaults[:completion_model],
115
114
  body: parameters.to_json,
116
115
  content_type: "application/json",
117
116
  accept: "application/json"
@@ -127,7 +126,7 @@ module Langchain::LLM
127
126
  # @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
128
127
  # @option params [Array<String>] :messages The messages to generate a completion for
129
128
  # @option params [String] :system The system prompt to provide instructions
130
- # @option params [String] :model The model to use for completion defaults to @defaults[:chat_completion_model_name]
129
+ # @option params [String] :model The model to use for completion defaults to @defaults[:chat_model]
131
130
  # @option params [Integer] :max_tokens The maximum number of tokens to generate defaults to @defaults[:max_tokens_to_sample]
132
131
  # @option params [Array<String>] :stop The stop sequences to use for completion
133
132
  # @option params [Array<String>] :stop_sequences The stop sequences to use for completion
@@ -176,11 +175,11 @@ module Langchain::LLM
176
175
  private
177
176
 
178
177
  def completion_provider
179
- @defaults[:completion_model_name].split(".").first.to_sym
178
+ @defaults[:completion_model].split(".").first.to_sym
180
179
  end
181
180
 
182
181
  def embedding_provider
183
- @defaults[:embedding_model_name].split(".").first.to_sym
182
+ @defaults[:embedding_model].split(".").first.to_sym
184
183
  end
185
184
 
186
185
  def wrap_prompt(prompt)
@@ -7,7 +7,7 @@ module Langchain::LLM
7
7
  # gem "ruby-openai", "~> 6.3.0"
8
8
  #
9
9
  # Usage:
10
- # openai = Langchain::LLM::Azure.new(api_key:, llm_options: {}, embedding_deployment_url: chat_deployment_url:)
10
+ # llm = Langchain::LLM::Azure.new(api_key:, llm_options: {}, embedding_deployment_url: chat_deployment_url:)
11
11
  #
12
12
  class Azure < OpenAI
13
13
  attr_reader :embed_client
@@ -33,7 +33,7 @@ module Langchain::LLM
33
33
  )
34
34
  @defaults = DEFAULTS.merge(default_options)
35
35
  chat_parameters.update(
36
- model: {default: @defaults[:chat_completion_model_name]},
36
+ model: {default: @defaults[:chat_model]},
37
37
  logprobs: {},
38
38
  top_logprobs: {},
39
39
  n: {default: @defaults[:n]},
@@ -34,7 +34,7 @@ module Langchain::LLM
34
34
  default_dimensions
35
35
  end
36
36
 
37
- # Returns the number of vector dimensions used by DEFAULTS[:chat_completion_model_name]
37
+ # Returns the number of vector dimensions used by DEFAULTS[:chat_model]
38
38
  #
39
39
  # @return [Integer] Vector dimensions
40
40
  def default_dimensions
@@ -13,9 +13,9 @@ module Langchain::LLM
13
13
  class Cohere < Base
14
14
  DEFAULTS = {
15
15
  temperature: 0.0,
16
- completion_model_name: "command",
17
- chat_completion_model_name: "command-r-plus",
18
- embeddings_model_name: "small",
16
+ completion_model: "command",
17
+ chat_model: "command-r-plus",
18
+ embedding_model: "small",
19
19
  dimensions: 1024,
20
20
  truncate: "START"
21
21
  }.freeze
@@ -26,7 +26,7 @@ module Langchain::LLM
26
26
  @client = ::Cohere::Client.new(api_key: api_key)
27
27
  @defaults = DEFAULTS.merge(default_options)
28
28
  chat_parameters.update(
29
- model: {default: @defaults[:chat_completion_model_name]},
29
+ model: {default: @defaults[:chat_model]},
30
30
  temperature: {default: @defaults[:temperature]},
31
31
  response_format: {default: @defaults[:response_format]}
32
32
  )
@@ -48,10 +48,10 @@ module Langchain::LLM
48
48
  def embed(text:)
49
49
  response = client.embed(
50
50
  texts: [text],
51
- model: @defaults[:embeddings_model_name]
51
+ model: @defaults[:embedding_model]
52
52
  )
53
53
 
54
- Langchain::LLM::CohereResponse.new response, model: @defaults[:embeddings_model_name]
54
+ Langchain::LLM::CohereResponse.new response, model: @defaults[:embedding_model]
55
55
  end
56
56
 
57
57
  #
@@ -65,7 +65,7 @@ module Langchain::LLM
65
65
  default_params = {
66
66
  prompt: prompt,
67
67
  temperature: @defaults[:temperature],
68
- model: @defaults[:completion_model_name],
68
+ model: @defaults[:completion_model],
69
69
  truncate: @defaults[:truncate]
70
70
  }
71
71
 
@@ -76,7 +76,7 @@ module Langchain::LLM
76
76
  default_params.merge!(params)
77
77
 
78
78
  response = client.generate(**default_params)
79
- Langchain::LLM::CohereResponse.new response, model: @defaults[:completion_model_name]
79
+ Langchain::LLM::CohereResponse.new response, model: @defaults[:completion_model]
80
80
  end
81
81
 
82
82
  # Generate a chat completion for given messages
@@ -5,8 +5,8 @@ module Langchain::LLM
5
5
  # llm = Langchain::LLM::GoogleGemini.new(api_key: ENV['GOOGLE_GEMINI_API_KEY'])
6
6
  class GoogleGemini < Base
7
7
  DEFAULTS = {
8
- chat_completion_model_name: "gemini-1.5-pro-latest",
9
- embeddings_model_name: "text-embedding-004",
8
+ chat_model: "gemini-1.5-pro-latest",
9
+ embedding_model: "text-embedding-004",
10
10
  temperature: 0.0
11
11
  }
12
12
 
@@ -17,10 +17,10 @@ module Langchain::LLM
17
17
  @defaults = DEFAULTS.merge(default_options)
18
18
 
19
19
  chat_parameters.update(
20
- model: {default: @defaults[:chat_completion_model_name]},
20
+ model: {default: @defaults[:chat_model]},
21
21
  temperature: {default: @defaults[:temperature]},
22
22
  generation_config: {default: nil},
23
- safety_settings: {default: nil}
23
+ safety_settings: {default: @defaults[:safety_settings]}
24
24
  )
25
25
  chat_parameters.remap(
26
26
  messages: :contents,
@@ -72,9 +72,8 @@ module Langchain::LLM
72
72
 
73
73
  def embed(
74
74
  text:,
75
- model: @defaults[:embeddings_model_name]
75
+ model: @defaults[:embedding_model]
76
76
  )
77
-
78
77
  params = {
79
78
  content: {
80
79
  parts: [
@@ -17,8 +17,8 @@ module Langchain::LLM
17
17
  top_p: 0.8,
18
18
  top_k: 40,
19
19
  dimensions: 768,
20
- embeddings_model_name: "textembedding-gecko",
21
- chat_completion_model_name: "gemini-1.0-pro"
20
+ embedding_model: "textembedding-gecko",
21
+ chat_model: "gemini-1.0-pro"
22
22
  }.freeze
23
23
 
24
24
  # Google Cloud has a project id and a specific region of deployment.
@@ -38,8 +38,9 @@ module Langchain::LLM
38
38
  @defaults = DEFAULTS.merge(default_options)
39
39
 
40
40
  chat_parameters.update(
41
- model: {default: @defaults[:chat_completion_model_name]},
42
- temperature: {default: @defaults[:temperature]}
41
+ model: {default: @defaults[:chat_model]},
42
+ temperature: {default: @defaults[:temperature]},
43
+ safety_settings: {default: @defaults[:safety_settings]}
43
44
  )
44
45
  chat_parameters.remap(
45
46
  messages: :contents,
@@ -57,7 +58,7 @@ module Langchain::LLM
57
58
  #
58
59
  def embed(
59
60
  text:,
60
- model: @defaults[:embeddings_model_name]
61
+ model: @defaults[:embedding_model]
61
62
  )
62
63
  params = {instances: [{content: text}]}
63
64
 
@@ -8,11 +8,11 @@ module Langchain::LLM
8
8
  # gem "hugging-face", "~> 0.3.4"
9
9
  #
10
10
  # Usage:
11
- # hf = Langchain::LLM::HuggingFace.new(api_key: ENV["HUGGING_FACE_API_KEY"])
11
+ # llm = Langchain::LLM::HuggingFace.new(api_key: ENV["HUGGING_FACE_API_KEY"])
12
12
  #
13
13
  class HuggingFace < Base
14
14
  DEFAULTS = {
15
- embeddings_model_name: "sentence-transformers/all-MiniLM-L6-v2"
15
+ embedding_model: "sentence-transformers/all-MiniLM-L6-v2"
16
16
  }.freeze
17
17
 
18
18
  EMBEDDING_SIZES = {
@@ -36,7 +36,7 @@ module Langchain::LLM
36
36
  def default_dimensions
37
37
  # since Huggin Face can run multiple models, look it up or generate an embedding and return the size
38
38
  @default_dimensions ||= @defaults[:dimensions] ||
39
- EMBEDDING_SIZES.fetch(@defaults[:embeddings_model_name].to_sym) do
39
+ EMBEDDING_SIZES.fetch(@defaults[:embedding_model].to_sym) do
40
40
  embed(text: "test").embedding.size
41
41
  end
42
42
  end
@@ -50,9 +50,9 @@ module Langchain::LLM
50
50
  def embed(text:)
51
51
  response = client.embedding(
52
52
  input: text,
53
- model: @defaults[:embeddings_model_name]
53
+ model: @defaults[:embedding_model]
54
54
  )
55
- Langchain::LLM::HuggingFaceResponse.new(response, model: @defaults[:embeddings_model_name])
55
+ Langchain::LLM::HuggingFaceResponse.new(response, model: @defaults[:embedding_model])
56
56
  end
57
57
  end
58
58
  end
@@ -8,8 +8,8 @@ module Langchain::LLM
8
8
  # llm = Langchain::LLM::MistralAI.new(api_key: ENV["MISTRAL_AI_API_KEY"])
9
9
  class MistralAI < Base
10
10
  DEFAULTS = {
11
- chat_completion_model_name: "mistral-large-latest",
12
- embeddings_model_name: "mistral-embed"
11
+ chat_model: "mistral-large-latest",
12
+ embedding_model: "mistral-embed"
13
13
  }.freeze
14
14
 
15
15
  attr_reader :defaults
@@ -24,7 +24,7 @@ module Langchain::LLM
24
24
 
25
25
  @defaults = DEFAULTS.merge(default_options)
26
26
  chat_parameters.update(
27
- model: {default: @defaults[:chat_completion_model_name]},
27
+ model: {default: @defaults[:chat_model]},
28
28
  n: {default: @defaults[:n]},
29
29
  safe_prompt: {},
30
30
  temperature: {default: @defaults[:temperature]},
@@ -44,7 +44,7 @@ module Langchain::LLM
44
44
 
45
45
  def embed(
46
46
  text:,
47
- model: defaults[:embeddings_model_name],
47
+ model: defaults[:embedding_model],
48
48
  encoding_format: nil
49
49
  )
50
50
  params = {
@@ -5,7 +5,6 @@ module Langchain::LLM
5
5
  # Available models: https://ollama.ai/library
6
6
  #
7
7
  # Usage:
8
- # llm = Langchain::LLM::Ollama.new
9
8
  # llm = Langchain::LLM::Ollama.new(url: ENV["OLLAMA_URL"], default_options: {})
10
9
  #
11
10
  class Ollama < Base
@@ -13,9 +12,9 @@ module Langchain::LLM
13
12
 
14
13
  DEFAULTS = {
15
14
  temperature: 0.0,
16
- completion_model_name: "llama3.1",
17
- embeddings_model_name: "llama3.1",
18
- chat_completion_model_name: "llama3.1"
15
+ completion_model: "llama3.1",
16
+ embedding_model: "llama3.1",
17
+ chat_model: "llama3.1"
19
18
  }.freeze
20
19
 
21
20
  EMBEDDING_SIZES = {
@@ -42,7 +41,7 @@ module Langchain::LLM
42
41
  @api_key = api_key
43
42
  @defaults = DEFAULTS.merge(default_options)
44
43
  chat_parameters.update(
45
- model: {default: @defaults[:chat_completion_model_name]},
44
+ model: {default: @defaults[:chat_model]},
46
45
  temperature: {default: @defaults[:temperature]},
47
46
  template: {},
48
47
  stream: {default: false},
@@ -56,7 +55,7 @@ module Langchain::LLM
56
55
  def default_dimensions
57
56
  # since Ollama can run multiple models, look it up or generate an embedding and return the size
58
57
  @default_dimensions ||=
59
- EMBEDDING_SIZES.fetch(defaults[:embeddings_model_name].to_sym) do
58
+ EMBEDDING_SIZES.fetch(defaults[:embedding_model].to_sym) do
60
59
  embed(text: "test").embedding.size
61
60
  end
62
61
  end
@@ -78,7 +77,7 @@ module Langchain::LLM
78
77
  #
79
78
  def complete(
80
79
  prompt:,
81
- model: defaults[:completion_model_name],
80
+ model: defaults[:completion_model],
82
81
  images: nil,
83
82
  format: nil,
84
83
  system: nil,
@@ -200,7 +199,7 @@ module Langchain::LLM
200
199
  #
201
200
  def embed(
202
201
  text:,
203
- model: defaults[:embeddings_model_name],
202
+ model: defaults[:embedding_model],
204
203
  mirostat: nil,
205
204
  mirostat_eta: nil,
206
205
  mirostat_tau: nil,
@@ -7,7 +7,7 @@ module Langchain::LLM
7
7
  # gem "ruby-openai", "~> 6.3.0"
8
8
  #
9
9
  # Usage:
10
- # openai = Langchain::LLM::OpenAI.new(
10
+ # llm = Langchain::LLM::OpenAI.new(
11
11
  # api_key: ENV["OPENAI_API_KEY"],
12
12
  # llm_options: {}, # Available options: https://github.com/alexrudall/ruby-openai/blob/main/lib/openai/client.rb#L5-L13
13
13
  # default_options: {}
@@ -16,8 +16,8 @@ module Langchain::LLM
16
16
  DEFAULTS = {
17
17
  n: 1,
18
18
  temperature: 0.0,
19
- chat_completion_model_name: "gpt-4o-mini",
20
- embeddings_model_name: "text-embedding-3-small"
19
+ chat_model: "gpt-4o-mini",
20
+ embedding_model: "text-embedding-3-small"
21
21
  }.freeze
22
22
 
23
23
  EMBEDDING_SIZES = {
@@ -41,7 +41,7 @@ module Langchain::LLM
41
41
 
42
42
  @defaults = DEFAULTS.merge(default_options)
43
43
  chat_parameters.update(
44
- model: {default: @defaults[:chat_completion_model_name]},
44
+ model: {default: @defaults[:chat_model]},
45
45
  logprobs: {},
46
46
  top_logprobs: {},
47
47
  n: {default: @defaults[:n]},
@@ -61,7 +61,7 @@ module Langchain::LLM
61
61
  # @return [Langchain::LLM::OpenAIResponse] Response object
62
62
  def embed(
63
63
  text:,
64
- model: defaults[:embeddings_model_name],
64
+ model: defaults[:embedding_model],
65
65
  encoding_format: nil,
66
66
  user: nil,
67
67
  dimensions: @defaults[:dimensions]
@@ -100,7 +100,7 @@ module Langchain::LLM
100
100
  # @param params [Hash] The parameters to pass to the `chat()` method
101
101
  # @return [Langchain::LLM::OpenAIResponse] Response object
102
102
  def complete(prompt:, **params)
103
- warn "DEPRECATED: `Langchain::LLM::OpenAI#complete` is deprecated, and will be removed in the next major version. Use `Langchain::LLM::OpenAI#chat` instead."
103
+ Langchain.logger.warn "DEPRECATED: `Langchain::LLM::OpenAI#complete` is deprecated, and will be removed in the next major version. Use `Langchain::LLM::OpenAI#chat` instead."
104
104
 
105
105
  if params[:stop_sequences]
106
106
  params[:stop] = params.delete(:stop_sequences)
@@ -109,6 +109,7 @@ module Langchain::LLM
109
109
  messages = [{role: "user", content: prompt}]
110
110
  chat(messages: messages, **params)
111
111
  end
112
+
112
113
  # rubocop:enable Style/ArgumentsForwarding
113
114
 
114
115
  # Generate a chat completion for given messages.
@@ -159,7 +160,7 @@ module Langchain::LLM
159
160
  end
160
161
 
161
162
  def default_dimensions
162
- @defaults[:dimensions] || EMBEDDING_SIZES.fetch(defaults[:embeddings_model_name])
163
+ @defaults[:dimensions] || EMBEDDING_SIZES.fetch(defaults[:embedding_model])
163
164
  end
164
165
 
165
166
  private
@@ -34,6 +34,7 @@ module Langchain::LLM::Parameters
34
34
  # Function-calling
35
35
  tools: {default: []},
36
36
  tool_choice: {},
37
+ parallel_tool_calls: {},
37
38
 
38
39
  # Additional optional parameters
39
40
  logit_bias: {}
@@ -7,23 +7,15 @@ module Langchain::LLM
7
7
  # Gem requirements:
8
8
  # gem "replicate-ruby", "~> 0.2.2"
9
9
  #
10
- # Use it directly:
11
- # replicate = Langchain::LLM::Replicate.new(api_key: ENV["REPLICATE_API_KEY"])
12
- #
13
- # Or pass it to be used by a vector search DB:
14
- # chroma = Langchain::Vectorsearch::Chroma.new(
15
- # url: ENV["CHROMA_URL"],
16
- # index_name: "...",
17
- # llm: replicate
18
- # )
19
- #
10
+ # Usage:
11
+ # llm = Langchain::LLM::Replicate.new(api_key: ENV["REPLICATE_API_KEY"])
20
12
  class Replicate < Base
21
13
  DEFAULTS = {
22
14
  # TODO: Figure out how to send the temperature to the API
23
15
  temperature: 0.01, # Minimum accepted value
24
16
  # TODO: Design the interface to pass and use different models
25
- completion_model_name: "replicate/vicuna-13b",
26
- embeddings_model_name: "creatorrr/all-mpnet-base-v2",
17
+ completion_model: "replicate/vicuna-13b",
18
+ embedding_model: "creatorrr/all-mpnet-base-v2",
27
19
  dimensions: 384
28
20
  }.freeze
29
21
 
@@ -57,7 +49,7 @@ module Langchain::LLM
57
49
  sleep(0.1)
58
50
  end
59
51
 
60
- Langchain::LLM::ReplicateResponse.new(response, model: @defaults[:embeddings_model_name])
52
+ Langchain::LLM::ReplicateResponse.new(response, model: @defaults[:embedding_model])
61
53
  end
62
54
 
63
55
  #
@@ -74,7 +66,7 @@ module Langchain::LLM
74
66
  sleep(0.1)
75
67
  end
76
68
 
77
- Langchain::LLM::ReplicateResponse.new(response, model: @defaults[:completion_model_name])
69
+ Langchain::LLM::ReplicateResponse.new(response, model: @defaults[:completion_model])
78
70
  end
79
71
 
80
72
  #
@@ -102,11 +94,11 @@ module Langchain::LLM
102
94
  private
103
95
 
104
96
  def completion_model
105
- @completion_model ||= client.retrieve_model(@defaults[:completion_model_name]).latest_version
97
+ @completion_model ||= client.retrieve_model(@defaults[:completion_model]).latest_version
106
98
  end
107
99
 
108
100
  def embeddings_model
109
- @embeddings_model ||= client.retrieve_model(@defaults[:embeddings_model_name]).latest_version
101
+ @embeddings_model ||= client.retrieve_model(@defaults[:embedding_model]).latest_version
110
102
  end
111
103
  end
112
104
  end
@@ -103,6 +103,13 @@ module Langchain::ToolDefinition
103
103
  # @return [String] JSON string of schemas in Anthropic format
104
104
  def to_anthropic_format
105
105
  @schemas.values.map do |schema|
106
+ # Adds a default input_schema if no parameters are present
107
+ schema[:function][:parameters] ||= {
108
+ type: "object",
109
+ properties: {},
110
+ required: []
111
+ }
112
+
106
113
  schema[:function].transform_keys(parameters: :input_schema)
107
114
  end
108
115
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
- VERSION = "0.17.1"
4
+ VERSION = "0.19.0"
5
5
  end
data/lib/langchain.rb CHANGED
@@ -22,25 +22,12 @@ loader.inflector.inflect(
22
22
  "mistral_ai_response" => "MistralAIResponse",
23
23
  "mistral_ai_message" => "MistralAIMessage",
24
24
  "openai" => "OpenAI",
25
- "openai_validator" => "OpenAIValidator",
26
25
  "openai_response" => "OpenAIResponse",
27
26
  "openai_message" => "OpenAIMessage",
28
27
  "pdf" => "PDF"
29
28
  )
29
+
30
30
  loader.collapse("#{__dir__}/langchain/llm/response")
31
- loader.collapse("#{__dir__}/langchain/assistants")
32
-
33
- loader.collapse("#{__dir__}/langchain/tool/calculator")
34
- loader.collapse("#{__dir__}/langchain/tool/database")
35
- loader.collapse("#{__dir__}/langchain/tool/docs_tool")
36
- loader.collapse("#{__dir__}/langchain/tool/file_system")
37
- loader.collapse("#{__dir__}/langchain/tool/google_search")
38
- loader.collapse("#{__dir__}/langchain/tool/ruby_code_interpreter")
39
- loader.collapse("#{__dir__}/langchain/tool/news_retriever")
40
- loader.collapse("#{__dir__}/langchain/tool/tavily")
41
- loader.collapse("#{__dir__}/langchain/tool/vectorsearch")
42
- loader.collapse("#{__dir__}/langchain/tool/weather")
43
- loader.collapse("#{__dir__}/langchain/tool/wikipedia")
44
31
 
45
32
  # RubyCodeInterpreter does not work with Ruby 3.3;
46
33
  # https://github.com/ukutaht/safe_ruby/issues/4