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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +6 -1
- data/lib/langchain/assistants/assistant.rb +25 -17
- data/lib/langchain/assistants/messages/base.rb +5 -1
- data/lib/langchain/assistants/messages/mistral_ai_message.rb +30 -8
- data/lib/langchain/assistants/messages/openai_message.rb +37 -8
- data/lib/langchain/llm/base.rb +1 -2
- data/lib/langchain/vectorsearch/elasticsearch.rb +1 -1
- data/lib/langchain/vectorsearch/milvus.rb +45 -61
- data/lib/langchain/vectorsearch/qdrant.rb +3 -2
- data/lib/langchain/vectorsearch/weaviate.rb +3 -2
- data/lib/langchain/version.rb +1 -1
- metadata +8 -24
- data/lib/langchain/llm/google_palm.rb +0 -177
- data/lib/langchain/llm/response/google_palm_response.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c125e87218ae9ce233711968edf212e128b50910f118951296593d141c9b7a68
|
4
|
+
data.tar.gz: a8e0890d5eef171709068ee19e4e0955929035d732225916e28debd03cfebcbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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
|
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
|
|
@@ -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 [
|
21
|
-
# @param [
|
22
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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 [
|
21
|
-
# @param [
|
22
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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
|
|
data/lib/langchain/llm/base.rb
CHANGED
@@ -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}
|
@@ -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
|
+
# gem "milvus", "~> 0.10.3"
|
10
10
|
#
|
11
11
|
# Usage:
|
12
|
-
#
|
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(
|
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
|
-
|
28
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
data_type: ::Milvus::DATA_TYPES["int64"]
|
60
|
+
fieldName: "id",
|
61
|
+
isPrimary: true,
|
62
|
+
dataType: "Int64"
|
72
63
|
}, {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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.
|
85
|
+
client.indexes.create(
|
101
86
|
collection_name: index_name,
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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.
|
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.
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
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.
|
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.
|
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
|
data/lib/langchain/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|