langchainrb 0.16.1 → 0.17.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: b078089a99e9e8d6654a244165ecc9d0f3dfdd8fbc0367623d41fe771a98ac41
4
- data.tar.gz: 890c371564ce9188087bed9eb053a59e11f7b734a44b9f753696f8458f8a7b7e
3
+ metadata.gz: c125e87218ae9ce233711968edf212e128b50910f118951296593d141c9b7a68
4
+ data.tar.gz: a8e0890d5eef171709068ee19e4e0955929035d732225916e28debd03cfebcbf
5
5
  SHA512:
6
- metadata.gz: 8f458bfae5af31190f41661a13c24e5cd63d5f88e594e854ee79ea3b8af1f51b20552f178c89c71e454a86e4d827b3facecd97f0fa3ef107b7b6097754fab5e3
7
- data.tar.gz: cfe0c684f89c5eef73ceb26b70292fe8fc4f941e13795ac98bd1d3197321a1303250d2584f9e45aa530e311304004911ffe3a6af7f606f6a733baad21ff2b814
6
+ metadata.gz: ae228197ef8be183cf9f36dc46bb523033fcfd1c563246e3f49bec081822b819d3ca1b93a0b5a780af276cb80ef3ce6ef6734e87f7cf3fad335d0e57e186e965
7
+ data.tar.gz: fd17a2caabbce6d6b006831e3eb51c6c3c174f178536991f6c0477aadc4d5ea64c2dae317cf59be9691908c0d0908cca6fac681eedc413b69588883cb6494a50
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.17.0] - 2024-10-02
4
+ - [BREAKING] Langchain::Vectorsearch::Milvus was rewritten to work with newer milvus 0.10.0 gem
5
+ - [BREAKING] Removing Langchain::LLM::GooglePalm
6
+ - Assistant can now process image_urls in the messages (currently only for OpenAI and Mistral AI)
7
+ - Vectorsearch providers utilize the global Langchain.logger
8
+ - Update required milvus, qdrant and weaviate versions
9
+
3
10
  ## [0.16.1] - 2024-09-30
4
11
  - Deprecate Langchain::LLM::GooglePalm
5
12
  - Allow setting response_object: {} parameter when initializing supported Langchain::LLM::* classes
data/README.md CHANGED
@@ -63,7 +63,6 @@ The `Langchain::LLM` module provides a unified interface for interacting with va
63
63
  - Azure OpenAI
64
64
  - Cohere
65
65
  - Google Gemini
66
- - Google PaLM (deprecated)
67
66
  - Google Vertex AI
68
67
  - HuggingFace
69
68
  - LlamaCpp
@@ -501,6 +500,12 @@ assistant = Langchain::Assistant.new(
501
500
  # Add a user message and run the assistant
502
501
  assistant.add_message_and_run!(content: "What's the latest news about AI?")
503
502
 
503
+ # Supply an image to the assistant
504
+ assistant.add_message_and_run!(
505
+ content: "Show me a picture of a cat",
506
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
507
+ )
508
+
504
509
  # Access the conversation thread
505
510
  messages = assistant.messages
506
511
 
@@ -63,13 +63,14 @@ module Langchain
63
63
 
64
64
  # Add a user message to the messages array
65
65
  #
66
- # @param content [String] The content of the message
67
66
  # @param role [String] The role attribute of the message. Default: "user"
67
+ # @param content [String] The content of the message
68
+ # @param image_url [String] The URL of the image to include in the message
68
69
  # @param tool_calls [Array<Hash>] The tool calls to include in the message
69
70
  # @param tool_call_id [String] The ID of the tool call to include in the message
70
71
  # @return [Array<Langchain::Message>] The messages
71
- def add_message(content: nil, role: "user", tool_calls: [], tool_call_id: nil)
72
- message = build_message(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
72
+ def add_message(role: "user", content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
73
+ message = build_message(role: role, content: content, image_url: image_url, tool_calls: tool_calls, tool_call_id: tool_call_id)
73
74
 
74
75
  # Call the callback with the message
75
76
  add_message_callback.call(message) if add_message_callback # rubocop:disable Style/SafeNavigation
@@ -145,8 +146,8 @@ module Langchain
145
146
  # @param content [String] The content of the message
146
147
  # @param auto_tool_execution [Boolean] Whether or not to automatically run tools
147
148
  # @return [Array<Langchain::Message>] The messages
148
- def add_message_and_run(content:, auto_tool_execution: false)
149
- add_message(content: content, role: "user")
149
+ def add_message_and_run(content: nil, image_url: nil, auto_tool_execution: false)
150
+ add_message(content: content, image_url: image_url, role: "user")
150
151
  run(auto_tool_execution: auto_tool_execution)
151
152
  end
152
153
 
@@ -154,8 +155,8 @@ module Langchain
154
155
  #
155
156
  # @param content [String] The content of the message
156
157
  # @return [Array<Langchain::Message>] The messages
157
- def add_message_and_run!(content:)
158
- add_message_and_run(content: content, auto_tool_execution: true)
158
+ def add_message_and_run!(content: nil, image_url: nil)
159
+ add_message_and_run(content: content, image_url: image_url, auto_tool_execution: true)
159
160
  end
160
161
 
161
162
  # Submit tool output
@@ -388,11 +389,12 @@ module Langchain
388
389
  #
389
390
  # @param role [String] The role of the message
390
391
  # @param content [String] The content of the message
392
+ # @param image_url [String] The URL of the image to include in the message
391
393
  # @param tool_calls [Array<Hash>] The tool calls to include in the message
392
394
  # @param tool_call_id [String] The ID of the tool call to include in the message
393
395
  # @return [Langchain::Message] The Message object
394
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
395
- @llm_adapter.build_message(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
396
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
397
+ @llm_adapter.build_message(role: role, content: content, image_url: image_url, tool_calls: tool_calls, tool_call_id: tool_call_id)
396
398
  end
397
399
 
398
400
  # Increment the tokens count based on the last interaction with the LLM
@@ -443,7 +445,7 @@ module Langchain
443
445
  raise NotImplementedError, "Subclasses must implement extract_tool_call_args"
444
446
  end
445
447
 
446
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
448
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
447
449
  raise NotImplementedError, "Subclasses must implement build_message"
448
450
  end
449
451
  end
@@ -457,7 +459,9 @@ module Langchain
457
459
  params
458
460
  end
459
461
 
460
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
462
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
463
+ warn "Image URL is not supported by Ollama currently" if image_url
464
+
461
465
  Langchain::Messages::OllamaMessage.new(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
462
466
  end
463
467
 
@@ -506,8 +510,8 @@ module Langchain
506
510
  params
507
511
  end
508
512
 
509
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
510
- Langchain::Messages::OpenAIMessage.new(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
513
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
514
+ Langchain::Messages::OpenAIMessage.new(role: role, content: content, image_url: image_url, tool_calls: tool_calls, tool_call_id: tool_call_id)
511
515
  end
512
516
 
513
517
  # Extract the tool call information from the OpenAI tool call hash
@@ -564,8 +568,8 @@ module Langchain
564
568
  params
565
569
  end
566
570
 
567
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
568
- Langchain::Messages::MistralAIMessage.new(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
571
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
572
+ Langchain::Messages::MistralAIMessage.new(role: role, content: content, image_url: image_url, tool_calls: tool_calls, tool_call_id: tool_call_id)
569
573
  end
570
574
 
571
575
  # Extract the tool call information from the OpenAI tool call hash
@@ -623,7 +627,9 @@ module Langchain
623
627
  params
624
628
  end
625
629
 
626
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
630
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
631
+ warn "Image URL is not supported by Google Gemini" if image_url
632
+
627
633
  Langchain::Messages::GoogleGeminiMessage.new(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
628
634
  end
629
635
 
@@ -676,7 +682,9 @@ module Langchain
676
682
  params
677
683
  end
678
684
 
679
- def build_message(role:, content: nil, tool_calls: [], tool_call_id: nil)
685
+ def build_message(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil)
686
+ warn "Image URL is not supported by Anthropic currently" if image_url
687
+
680
688
  Langchain::Messages::AnthropicMessage.new(role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id)
681
689
  end
682
690
 
@@ -3,7 +3,11 @@
3
3
  module Langchain
4
4
  module Messages
5
5
  class Base
6
- attr_reader :role, :content, :tool_calls, :tool_call_id
6
+ attr_reader :role,
7
+ :content,
8
+ :image_url,
9
+ :tool_calls,
10
+ :tool_call_id
7
11
 
8
12
  # Check if the message came from a user
9
13
  #
@@ -15,17 +15,20 @@ module Langchain
15
15
 
16
16
  # Initialize a new MistralAI message
17
17
  #
18
- # @param [String] The role of the message
19
- # @param [String] The content of the message
20
- # @param [Array<Hash>] The tool calls made in the message
21
- # @param [String] The ID of the tool call
22
- def initialize(role:, content: nil, tool_calls: [], tool_call_id: nil) # TODO: Implement image_file: reference (https://platform.openai.com/docs/api-reference/messages/object#messages/object-content)
18
+ # @param role [String] The role of the message
19
+ # @param content [String] The content of the message
20
+ # @param image_url [String] The URL of the image
21
+ # @param tool_calls [Array<Hash>] The tool calls made in the message
22
+ # @param tool_call_id [String] The ID of the tool call
23
+ def initialize(role:, content: nil, image_url: nil, tool_calls: [], tool_call_id: nil) # TODO: Implement image_file: reference (https://platform.openai.com/docs/api-reference/messages/object#messages/object-content)
23
24
  raise ArgumentError, "Role must be one of #{ROLES.join(", ")}" unless ROLES.include?(role)
24
25
  raise ArgumentError, "Tool calls must be an array of hashes" unless tool_calls.is_a?(Array) && tool_calls.all? { |tool_call| tool_call.is_a?(Hash) }
25
26
 
26
27
  @role = role
27
28
  # Some Tools return content as a JSON hence `.to_s`
28
29
  @content = content.to_s
30
+ # Make sure you're using the Pixtral model if you want to send image_url
31
+ @image_url = image_url
29
32
  @tool_calls = tool_calls
30
33
  @tool_call_id = tool_call_id
31
34
  end
@@ -43,9 +46,28 @@ module Langchain
43
46
  def to_hash
44
47
  {}.tap do |h|
45
48
  h[:role] = role
46
- h[:content] = content if content # Content is nil for tool calls
47
- h[:tool_calls] = tool_calls if tool_calls.any?
48
- h[:tool_call_id] = tool_call_id if tool_call_id
49
+
50
+ if tool_calls.any?
51
+ h[:tool_calls] = tool_calls
52
+ else
53
+ h[:tool_call_id] = tool_call_id if tool_call_id
54
+
55
+ h[:content] = []
56
+
57
+ if content && !content.empty?
58
+ h[:content] << {
59
+ type: "text",
60
+ text: content
61
+ }
62
+ end
63
+
64
+ if image_url
65
+ h[:content] << {
66
+ type: "image_url",
67
+ image_url: image_url
68
+ }
69
+ end
70
+ end
49
71
  end
50
72
  end
51
73
 
@@ -15,17 +15,25 @@ module Langchain
15
15
 
16
16
  # Initialize a new OpenAI message
17
17
  #
18
- # @param [String] The role of the message
19
- # @param [String] The content of the message
20
- # @param [Array<Hash>] The tool calls made in the message
21
- # @param [String] The ID of the tool call
22
- def initialize(role:, content: nil, tool_calls: [], tool_call_id: nil) # TODO: Implement image_file: reference (https://platform.openai.com/docs/api-reference/messages/object#messages/object-content)
18
+ # @param role [String] The role of the message
19
+ # @param content [String] The content of the message
20
+ # @param image_url [String] The URL of the image
21
+ # @param tool_calls [Array<Hash>] The tool calls made in the message
22
+ # @param tool_call_id [String] The ID of the tool call
23
+ def initialize(
24
+ role:,
25
+ content: nil,
26
+ image_url: nil,
27
+ tool_calls: [],
28
+ tool_call_id: nil
29
+ )
23
30
  raise ArgumentError, "Role must be one of #{ROLES.join(", ")}" unless ROLES.include?(role)
24
31
  raise ArgumentError, "Tool calls must be an array of hashes" unless tool_calls.is_a?(Array) && tool_calls.all? { |tool_call| tool_call.is_a?(Hash) }
25
32
 
26
33
  @role = role
27
34
  # Some Tools return content as a JSON hence `.to_s`
28
35
  @content = content.to_s
36
+ @image_url = image_url
29
37
  @tool_calls = tool_calls
30
38
  @tool_call_id = tool_call_id
31
39
  end
@@ -43,9 +51,30 @@ module Langchain
43
51
  def to_hash
44
52
  {}.tap do |h|
45
53
  h[:role] = role
46
- h[:content] = content if content # Content is nil for tool calls
47
- h[:tool_calls] = tool_calls if tool_calls.any?
48
- h[:tool_call_id] = tool_call_id if tool_call_id
54
+
55
+ if tool_calls.any?
56
+ h[:tool_calls] = tool_calls
57
+ else
58
+ h[:tool_call_id] = tool_call_id if tool_call_id
59
+
60
+ h[:content] = []
61
+
62
+ if content && !content.empty?
63
+ h[:content] << {
64
+ type: "text",
65
+ text: content
66
+ }
67
+ end
68
+
69
+ if image_url
70
+ h[:content] << {
71
+ type: "image_url",
72
+ image_url: {
73
+ url: image_url
74
+ }
75
+ }
76
+ end
77
+ end
49
78
  end
50
79
  end
51
80
 
@@ -11,9 +11,8 @@ module Langchain::LLM
11
11
  # - {Langchain::LLM::Anthropic}
12
12
  # - {Langchain::LLM::Azure}
13
13
  # - {Langchain::LLM::Cohere}
14
- # - {Langchain::LLM::GooglePalm}
15
- # - {Langchain::LLM::GoogleVertexAI}
16
14
  # - {Langchain::LLM::GoogleGemini}
15
+ # - {Langchain::LLM::GoogleVertexAI}
17
16
  # - {Langchain::LLM::HuggingFace}
18
17
  # - {Langchain::LLM::LlamaCpp}
19
18
  # - {Langchain::LLM::OpenAI}
@@ -37,7 +37,7 @@ module Langchain::Vectorsearch
37
37
  @options = {
38
38
  url: url,
39
39
  request_timeout: 20,
40
- log: false
40
+ logger: Langchain.logger
41
41
  }.merge(es_options)
42
42
 
43
43
  @es_client = ::Elasticsearch::Client.new(**options)
@@ -6,16 +6,18 @@ module Langchain::Vectorsearch
6
6
  # Wrapper around Milvus REST APIs.
7
7
  #
8
8
  # Gem requirements:
9
- # gem "milvus", "~> 0.9.3"
9
+ # gem "milvus", "~> 0.10.3"
10
10
  #
11
11
  # Usage:
12
- # milvus = Langchain::Vectorsearch::Milvus.new(url:, index_name:, llm:, api_key:)
12
+ # milvus = Langchain::Vectorsearch::Milvus.new(url:, index_name:, llm:, api_key:)
13
13
  #
14
-
15
14
  def initialize(url:, index_name:, llm:, api_key: nil)
16
15
  depends_on "milvus"
17
16
 
18
- @client = ::Milvus::Client.new(url: url)
17
+ @client = ::Milvus::Client.new(
18
+ url: url,
19
+ logger: Langchain.logger
20
+ )
19
21
  @index_name = index_name
20
22
 
21
23
  super(llm: llm)
@@ -24,33 +26,24 @@ module Langchain::Vectorsearch
24
26
  def add_texts(texts:)
25
27
  client.entities.insert(
26
28
  collection_name: index_name,
27
- num_rows: Array(texts).size,
28
- fields_data: [
29
- {
30
- field_name: "content",
31
- type: ::Milvus::DATA_TYPES["varchar"],
32
- field: Array(texts)
33
- }, {
34
- field_name: "vectors",
35
- type: ::Milvus::DATA_TYPES["float_vector"],
36
- field: Array(texts).map { |text| llm.embed(text: text).embedding }
37
- }
38
- ]
29
+ data: texts.map do |text|
30
+ {content: text, vector: llm.embed(text: text).embedding}
31
+ end
39
32
  )
40
33
  end
41
34
 
35
+ # TODO: Add update_texts method
36
+
42
37
  # Deletes a list of texts in the index
43
38
  #
44
39
  # @param ids [Array<Integer>] The ids of texts to delete
45
40
  # @return [Boolean] The response from the server
46
41
  def remove_texts(ids:)
47
42
  raise ArgumentError, "ids must be an array" unless ids.is_a?(Array)
48
- # Convert ids to integers if strings are passed
49
- ids = ids.map(&:to_i)
50
43
 
51
44
  client.entities.delete(
52
45
  collection_name: index_name,
53
- expression: "id in #{ids}"
46
+ filter: "id in #{ids}"
54
47
  )
55
48
  end
56
49
 
@@ -62,33 +55,25 @@ module Langchain::Vectorsearch
62
55
  client.collections.create(
63
56
  auto_id: true,
64
57
  collection_name: index_name,
65
- description: "Default schema created by langchain.rb",
66
58
  fields: [
67
59
  {
68
- name: "id",
69
- is_primary_key: true,
70
- autoID: true,
71
- data_type: ::Milvus::DATA_TYPES["int64"]
60
+ fieldName: "id",
61
+ isPrimary: true,
62
+ dataType: "Int64"
72
63
  }, {
73
- name: "content",
74
- is_primary_key: false,
75
- data_type: ::Milvus::DATA_TYPES["varchar"],
76
- type_params: [
77
- {
78
- key: "max_length",
79
- value: "32768" # Largest allowed value
80
- }
81
- ]
64
+ fieldName: "content",
65
+ isPrimary: false,
66
+ dataType: "VarChar",
67
+ elementTypeParams: {
68
+ max_length: "32768" # Largest allowed value
69
+ }
82
70
  }, {
83
- name: "vectors",
84
- data_type: ::Milvus::DATA_TYPES["float_vector"],
85
- is_primary_key: false,
86
- type_params: [
87
- {
88
- key: "dim",
89
- value: llm.default_dimensions.to_s
90
- }
91
- ]
71
+ fieldName: "vector",
72
+ isPrimary: false,
73
+ dataType: "FloatVector",
74
+ elementTypeParams: {
75
+ dim: llm.default_dimensions.to_s
76
+ }
92
77
  }
93
78
  ]
94
79
  )
@@ -97,13 +82,17 @@ module Langchain::Vectorsearch
97
82
  # Create the default index
98
83
  # @return [Boolean] The response from the server
99
84
  def create_default_index
100
- client.indices.create(
85
+ client.indexes.create(
101
86
  collection_name: index_name,
102
- field_name: "vectors",
103
- extra_params: [
104
- {key: "metric_type", value: "L2"},
105
- {key: "index_type", value: "IVF_FLAT"},
106
- {key: "params", value: "{\"nlist\":1024}"}
87
+ index_params: [
88
+ {
89
+ metricType: "L2",
90
+ fieldName: "vector",
91
+ indexName: "vector_idx",
92
+ indexConfig: {
93
+ index_type: "AUTOINDEX"
94
+ }
95
+ }
107
96
  ]
108
97
  )
109
98
  end
@@ -111,13 +100,13 @@ module Langchain::Vectorsearch
111
100
  # Get the default schema
112
101
  # @return [Hash] The response from the server
113
102
  def get_default_schema
114
- client.collections.get(collection_name: index_name)
103
+ client.collections.describe(collection_name: index_name)
115
104
  end
116
105
 
117
106
  # Delete default schema
118
107
  # @return [Hash] The response from the server
119
108
  def destroy_default_schema
120
- client.collections.delete(collection_name: index_name)
109
+ client.collections.drop(collection_name: index_name)
121
110
  end
122
111
 
123
112
  # Load default schema into memory
@@ -138,16 +127,12 @@ module Langchain::Vectorsearch
138
127
  def similarity_search_by_vector(embedding:, k: 4)
139
128
  load_default_schema
140
129
 
141
- client.search(
130
+ client.entities.search(
142
131
  collection_name: index_name,
143
- output_fields: ["id", "content"], # Add "vectors" if need to have full vectors returned.
144
- top_k: k.to_s,
145
- vectors: [embedding],
146
- dsl_type: 1,
147
- params: "{\"nprobe\": 10}",
148
- anns_field: "vectors",
149
- metric_type: "L2",
150
- vector_type: ::Milvus::DATA_TYPES["float_vector"]
132
+ anns_field: "vector",
133
+ data: [embedding],
134
+ limit: k,
135
+ output_fields: ["content", "id", "vector"]
151
136
  )
152
137
  end
153
138
 
@@ -159,8 +144,7 @@ module Langchain::Vectorsearch
159
144
  def ask(question:, k: 4, &block)
160
145
  search_results = similarity_search(query: question, k: k)
161
146
 
162
- content_field = search_results.dig("results", "fields_data").select { |field| field.dig("field_name") == "content" }
163
- content_data = content_field.first.dig("Field", "Scalars", "Data", "StringData", "data")
147
+ content_data = search_results.dig("data").map { |result| result.dig("content") }
164
148
 
165
149
  context = content_data.join("\n---\n")
166
150
 
@@ -6,7 +6,7 @@ module Langchain::Vectorsearch
6
6
  # Wrapper around Qdrant
7
7
  #
8
8
  # Gem requirements:
9
- # gem "qdrant-ruby", "~> 0.9.3"
9
+ # gem "qdrant-ruby", "~> 0.9.8"
10
10
  #
11
11
  # Usage:
12
12
  # qdrant = Langchain::Vectorsearch::Qdrant.new(url:, api_key:, index_name:, llm:)
@@ -22,7 +22,8 @@ module Langchain::Vectorsearch
22
22
 
23
23
  @client = ::Qdrant::Client.new(
24
24
  url: url,
25
- api_key: api_key
25
+ api_key: api_key,
26
+ logger: Langchain.logger
26
27
  )
27
28
  @index_name = index_name
28
29
 
@@ -6,7 +6,7 @@ module Langchain::Vectorsearch
6
6
  # Wrapper around Weaviate
7
7
  #
8
8
  # Gem requirements:
9
- # gem "weaviate-ruby", "~> 0.9.0"
9
+ # gem "weaviate-ruby", "~> 0.9.2"
10
10
  #
11
11
  # Usage:
12
12
  # weaviate = Langchain::Vectorsearch::Weaviate.new(url: ENV["WEAVIATE_URL"], api_key: ENV["WEAVIATE_API_KEY"], index_name: "Docs", llm: llm)
@@ -22,7 +22,8 @@ module Langchain::Vectorsearch
22
22
 
23
23
  @client = ::Weaviate::Client.new(
24
24
  url: url,
25
- api_key: api_key
25
+ api_key: api_key,
26
+ logger: Langchain.logger
26
27
  )
27
28
 
28
29
  # Weaviate requires the class name to be Capitalized: https://weaviate.io/developers/weaviate/configuration/schema-configuration#create-a-class
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
- VERSION = "0.16.1"
4
+ VERSION = "0.17.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langchainrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Bondarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-30 00:00:00.000000000 Z
11
+ date: 2024-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: baran
@@ -318,20 +318,6 @@ dependencies:
318
318
  - - ">="
319
319
  - !ruby/object:Gem::Version
320
320
  version: '0'
321
- - !ruby/object:Gem::Dependency
322
- name: google_palm_api
323
- requirement: !ruby/object:Gem::Requirement
324
- requirements:
325
- - - "~>"
326
- - !ruby/object:Gem::Version
327
- version: 0.1.3
328
- type: :development
329
- prerelease: false
330
- version_requirements: !ruby/object:Gem::Requirement
331
- requirements:
332
- - - "~>"
333
- - !ruby/object:Gem::Version
334
- version: 0.1.3
335
321
  - !ruby/object:Gem::Dependency
336
322
  name: google_search_results
337
323
  requirement: !ruby/object:Gem::Requirement
@@ -380,14 +366,14 @@ dependencies:
380
366
  requirements:
381
367
  - - "~>"
382
368
  - !ruby/object:Gem::Version
383
- version: 0.9.3
369
+ version: 0.10.3
384
370
  type: :development
385
371
  prerelease: false
386
372
  version_requirements: !ruby/object:Gem::Requirement
387
373
  requirements:
388
374
  - - "~>"
389
375
  - !ruby/object:Gem::Version
390
- version: 0.9.3
376
+ version: 0.10.3
391
377
  - !ruby/object:Gem::Dependency
392
378
  name: llama_cpp
393
379
  requirement: !ruby/object:Gem::Requirement
@@ -520,14 +506,14 @@ dependencies:
520
506
  requirements:
521
507
  - - "~>"
522
508
  - !ruby/object:Gem::Version
523
- version: 0.9.4
509
+ version: 0.9.8
524
510
  type: :development
525
511
  prerelease: false
526
512
  version_requirements: !ruby/object:Gem::Requirement
527
513
  requirements:
528
514
  - - "~>"
529
515
  - !ruby/object:Gem::Version
530
- version: 0.9.4
516
+ version: 0.9.8
531
517
  - !ruby/object:Gem::Dependency
532
518
  name: roo
533
519
  requirement: !ruby/object:Gem::Requirement
@@ -604,14 +590,14 @@ dependencies:
604
590
  requirements:
605
591
  - - "~>"
606
592
  - !ruby/object:Gem::Version
607
- version: 0.8.10
593
+ version: 0.9.2
608
594
  type: :development
609
595
  prerelease: false
610
596
  version_requirements: !ruby/object:Gem::Requirement
611
597
  requirements:
612
598
  - - "~>"
613
599
  - !ruby/object:Gem::Version
614
- version: 0.8.10
600
+ version: 0.9.2
615
601
  - !ruby/object:Gem::Dependency
616
602
  name: wikipedia-client
617
603
  requirement: !ruby/object:Gem::Requirement
@@ -683,7 +669,6 @@ files:
683
669
  - lib/langchain/llm/base.rb
684
670
  - lib/langchain/llm/cohere.rb
685
671
  - lib/langchain/llm/google_gemini.rb
686
- - lib/langchain/llm/google_palm.rb
687
672
  - lib/langchain/llm/google_vertex_ai.rb
688
673
  - lib/langchain/llm/hugging_face.rb
689
674
  - lib/langchain/llm/llama_cpp.rb
@@ -701,7 +686,6 @@ files:
701
686
  - lib/langchain/llm/response/base_response.rb
702
687
  - lib/langchain/llm/response/cohere_response.rb
703
688
  - lib/langchain/llm/response/google_gemini_response.rb
704
- - lib/langchain/llm/response/google_palm_response.rb
705
689
  - lib/langchain/llm/response/hugging_face_response.rb
706
690
  - lib/langchain/llm/response/llama_cpp_response.rb
707
691
  - lib/langchain/llm/response/mistral_ai_response.rb
@@ -1,177 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Langchain::LLM
4
- #
5
- # Wrapper around the Google PaLM (Pathways Language Model) APIs: https://ai.google/build/machine-learning/
6
- #
7
- # Gem requirements:
8
- # gem "google_palm_api", "~> 0.1.3"
9
- #
10
- # Usage:
11
- # google_palm = Langchain::LLM::GooglePalm.new(api_key: ENV["GOOGLE_PALM_API_KEY"])
12
- #
13
- class GooglePalm < Base
14
- extend Gem::Deprecate
15
-
16
- DEFAULTS = {
17
- temperature: 0.0,
18
- dimensions: 768, # This is what the `embedding-gecko-001` model generates
19
- completion_model_name: "text-bison-001",
20
- chat_completion_model_name: "chat-bison-001",
21
- embeddings_model_name: "embedding-gecko-001"
22
- }.freeze
23
-
24
- ROLE_MAPPING = {
25
- "assistant" => "ai"
26
- }
27
-
28
- attr_reader :defaults
29
-
30
- # @deprecated Please use Langchain::LLM::GoogleGemini instead
31
- #
32
- # @param api_key [String] The API key for the Google PaLM API
33
- def initialize(api_key:, default_options: {})
34
- depends_on "google_palm_api"
35
-
36
- @client = ::GooglePalmApi::Client.new(api_key: api_key)
37
- @defaults = DEFAULTS.merge(default_options)
38
- end
39
- deprecate :initialize, "Langchain::LLM::GoogleGemini.new(api_key:)", 2024, 10
40
-
41
- #
42
- # Generate an embedding for a given text
43
- #
44
- # @param text [String] The text to generate an embedding for
45
- # @return [Langchain::LLM::GooglePalmResponse] Response object
46
- #
47
- def embed(text:)
48
- response = client.embed(text: text)
49
-
50
- Langchain::LLM::GooglePalmResponse.new response,
51
- model: @defaults[:embeddings_model_name]
52
- end
53
-
54
- #
55
- # Generate a completion for a given prompt
56
- #
57
- # @param prompt [String] The prompt to generate a completion for
58
- # @param params extra parameters passed to GooglePalmAPI::Client#generate_text
59
- # @return [Langchain::LLM::GooglePalmResponse] Response object
60
- #
61
- def complete(prompt:, **params)
62
- default_params = {
63
- prompt: prompt,
64
- temperature: @defaults[:temperature],
65
- model: @defaults[:completion_model_name]
66
- }
67
-
68
- if params[:stop_sequences]
69
- default_params[:stop_sequences] = params.delete(:stop_sequences)
70
- end
71
-
72
- if params[:max_tokens]
73
- default_params[:max_output_tokens] = params.delete(:max_tokens)
74
- end
75
-
76
- default_params.merge!(params)
77
-
78
- response = client.generate_text(**default_params)
79
-
80
- Langchain::LLM::GooglePalmResponse.new response,
81
- model: default_params[:model]
82
- end
83
-
84
- #
85
- # Generate a chat completion for a given prompt
86
- #
87
- # @param prompt [String] The prompt to generate a chat completion for
88
- # @param messages [Array<Hash>] The messages that have been sent in the conversation
89
- # @param context [String] An initial context to provide as a system message, ie "You are RubyGPT, a helpful chat bot for helping people learn Ruby"
90
- # @param examples [Array<Hash>] Examples of messages to provide to the model. Useful for Few-Shot Prompting
91
- # @param options [Hash] extra parameters passed to GooglePalmAPI::Client#generate_chat_message
92
- # @return [Langchain::LLM::GooglePalmResponse] Response object
93
- #
94
- def chat(prompt: "", messages: [], context: "", examples: [], **options)
95
- raise ArgumentError.new(":prompt or :messages argument is expected") if prompt.empty? && messages.empty?
96
-
97
- default_params = {
98
- temperature: @defaults[:temperature],
99
- model: @defaults[:chat_completion_model_name],
100
- context: context,
101
- messages: compose_chat_messages(prompt: prompt, messages: messages),
102
- examples: compose_examples(examples)
103
- }
104
-
105
- if options[:stop_sequences]
106
- default_params[:stop] = options.delete(:stop_sequences)
107
- end
108
-
109
- if options[:max_tokens]
110
- default_params[:max_output_tokens] = options.delete(:max_tokens)
111
- end
112
-
113
- default_params.merge!(options)
114
-
115
- response = client.generate_chat_message(**default_params)
116
- raise "GooglePalm API returned an error: #{response}" if response.dig("error")
117
-
118
- Langchain::LLM::GooglePalmResponse.new response,
119
- model: default_params[:model]
120
- # TODO: Pass in prompt_tokens: prompt_tokens
121
- end
122
-
123
- #
124
- # Generate a summarization for a given text
125
- #
126
- # @param text [String] The text to generate a summarization for
127
- # @return [String] The summarization
128
- #
129
- def summarize(text:)
130
- prompt_template = Langchain::Prompt.load_from_path(
131
- file_path: Langchain.root.join("langchain/llm/prompts/summarize_template.yaml")
132
- )
133
- prompt = prompt_template.format(text: text)
134
-
135
- complete(
136
- prompt: prompt,
137
- temperature: @defaults[:temperature],
138
- # Most models have a context length of 2048 tokens (except for the newest models, which support 4096).
139
- max_tokens: 256
140
- )
141
- end
142
-
143
- private
144
-
145
- def compose_chat_messages(prompt:, messages:)
146
- history = []
147
- history.concat transform_messages(messages) unless messages.empty?
148
-
149
- unless prompt.empty?
150
- if history.last && history.last[:role] == "user"
151
- history.last[:content] += "\n#{prompt}"
152
- else
153
- history.append({author: "user", content: prompt})
154
- end
155
- end
156
- history
157
- end
158
-
159
- def compose_examples(examples)
160
- examples.each_slice(2).map do |example|
161
- {
162
- input: {content: example.first[:content]},
163
- output: {content: example.last[:content]}
164
- }
165
- end
166
- end
167
-
168
- def transform_messages(messages)
169
- messages.map do |message|
170
- {
171
- author: ROLE_MAPPING.fetch(message[:role], message[:role]),
172
- content: message[:content]
173
- }
174
- end
175
- end
176
- end
177
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Langchain::LLM
4
- class GooglePalmResponse < BaseResponse
5
- attr_reader :prompt_tokens
6
-
7
- def initialize(raw_response, model: nil, prompt_tokens: nil)
8
- @prompt_tokens = prompt_tokens
9
- super(raw_response, model: model)
10
- end
11
-
12
- def completion
13
- completions&.dig(0, "output")
14
- end
15
-
16
- def embedding
17
- embeddings.first
18
- end
19
-
20
- def completions
21
- raw_response.dig("candidates")
22
- end
23
-
24
- def chat_completion
25
- chat_completions&.dig(0, "content")
26
- end
27
-
28
- def chat_completions
29
- raw_response.dig("candidates")
30
- end
31
-
32
- def embeddings
33
- [raw_response.dig("embedding", "value")]
34
- end
35
-
36
- def role
37
- "assistant"
38
- end
39
- end
40
- end