langchainrb 0.16.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
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