langchainrb 0.8.2 → 0.9.1
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +57 -27
- data/lib/langchain/assistants/assistant.rb +199 -0
- data/lib/langchain/assistants/message.rb +58 -0
- data/lib/langchain/assistants/thread.rb +34 -0
- data/lib/langchain/conversation/memory.rb +1 -6
- data/lib/langchain/conversation.rb +7 -18
- data/lib/langchain/llm/ai21.rb +1 -1
- data/lib/langchain/llm/azure.rb +10 -97
- data/lib/langchain/llm/base.rb +1 -0
- data/lib/langchain/llm/cohere.rb +4 -6
- data/lib/langchain/llm/google_palm.rb +2 -0
- data/lib/langchain/llm/google_vertex_ai.rb +12 -10
- data/lib/langchain/llm/ollama.rb +167 -27
- data/lib/langchain/llm/openai.rb +104 -160
- data/lib/langchain/llm/replicate.rb +0 -6
- data/lib/langchain/llm/response/anthropic_response.rb +4 -0
- data/lib/langchain/llm/response/base_response.rb +7 -0
- data/lib/langchain/llm/response/google_palm_response.rb +4 -0
- data/lib/langchain/llm/response/ollama_response.rb +22 -0
- data/lib/langchain/llm/response/openai_response.rb +8 -0
- data/lib/langchain/tool/base.rb +24 -0
- data/lib/langchain/tool/google_search.rb +1 -4
- data/lib/langchain/utils/token_length/ai21_validator.rb +2 -2
- data/lib/langchain/utils/token_length/cohere_validator.rb +2 -2
- data/lib/langchain/utils/token_length/google_palm_validator.rb +2 -2
- data/lib/langchain/utils/token_length/openai_validator.rb +13 -2
- data/lib/langchain/utils/token_length/token_limit_exceeded.rb +1 -1
- data/lib/langchain/vectorsearch/pinecone.rb +2 -1
- data/lib/langchain/version.rb +1 -1
- data/lib/langchain.rb +2 -1
- metadata +24 -7
data/lib/langchain/llm/azure.rb
CHANGED
@@ -4,7 +4,7 @@ module Langchain::LLM
|
|
4
4
|
# LLM interface for Azure OpenAI Service APIs: https://learn.microsoft.com/en-us/azure/ai-services/openai/
|
5
5
|
#
|
6
6
|
# Gem requirements:
|
7
|
-
# gem "ruby-openai", "~> 6.
|
7
|
+
# gem "ruby-openai", "~> 6.3.0"
|
8
8
|
#
|
9
9
|
# Usage:
|
10
10
|
# openai = Langchain::LLM::Azure.new(api_key:, llm_options: {}, embedding_deployment_url: chat_deployment_url:)
|
@@ -34,106 +34,19 @@ module Langchain::LLM
|
|
34
34
|
@defaults = DEFAULTS.merge(default_options)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# @param text [String] The text to generate an embedding for
|
41
|
-
# @param params extra parameters passed to OpenAI::Client#embeddings
|
42
|
-
# @return [Langchain::LLM::OpenAIResponse] Response object
|
43
|
-
#
|
44
|
-
def embed(text:, **params)
|
45
|
-
parameters = {model: @defaults[:embeddings_model_name], input: text}
|
46
|
-
|
47
|
-
validate_max_tokens(text, parameters[:model])
|
48
|
-
|
49
|
-
response = with_api_error_handling do
|
50
|
-
embed_client.embeddings(parameters: parameters.merge(params))
|
51
|
-
end
|
52
|
-
|
53
|
-
Langchain::LLM::OpenAIResponse.new(response)
|
37
|
+
def embed(...)
|
38
|
+
@client = @embed_client
|
39
|
+
super(...)
|
54
40
|
end
|
55
41
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# @param prompt [String] The prompt to generate a completion for
|
60
|
-
# @param params extra parameters passed to OpenAI::Client#complete
|
61
|
-
# @return [Langchain::LLM::Response::OpenaAI] Response object
|
62
|
-
#
|
63
|
-
def complete(prompt:, **params)
|
64
|
-
parameters = compose_parameters @defaults[:completion_model_name], params
|
65
|
-
|
66
|
-
parameters[:messages] = compose_chat_messages(prompt: prompt)
|
67
|
-
parameters[:max_tokens] = validate_max_tokens(parameters[:messages], parameters[:model])
|
68
|
-
|
69
|
-
response = with_api_error_handling do
|
70
|
-
chat_client.chat(parameters: parameters)
|
71
|
-
end
|
72
|
-
|
73
|
-
Langchain::LLM::OpenAIResponse.new(response)
|
42
|
+
def complete(...)
|
43
|
+
@client = @chat_client
|
44
|
+
super(...)
|
74
45
|
end
|
75
46
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
# == Examples
|
80
|
-
#
|
81
|
-
# # simplest case, just give a prompt
|
82
|
-
# openai.chat prompt: "When was Ruby first released?"
|
83
|
-
#
|
84
|
-
# # prompt plus some context about how to respond
|
85
|
-
# openai.chat context: "You are RubyGPT, a helpful chat bot for helping people learn Ruby", prompt: "Does Ruby have a REPL like IPython?"
|
86
|
-
#
|
87
|
-
# # full control over messages that get sent, equivilent to the above
|
88
|
-
# openai.chat messages: [
|
89
|
-
# {
|
90
|
-
# role: "system",
|
91
|
-
# content: "You are RubyGPT, a helpful chat bot for helping people learn Ruby", prompt: "Does Ruby have a REPL like IPython?"
|
92
|
-
# },
|
93
|
-
# {
|
94
|
-
# role: "user",
|
95
|
-
# content: "When was Ruby first released?"
|
96
|
-
# }
|
97
|
-
# ]
|
98
|
-
#
|
99
|
-
# # few-short prompting with examples
|
100
|
-
# openai.chat prompt: "When was factory_bot released?",
|
101
|
-
# examples: [
|
102
|
-
# {
|
103
|
-
# role: "user",
|
104
|
-
# content: "When was Ruby on Rails released?"
|
105
|
-
# }
|
106
|
-
# {
|
107
|
-
# role: "assistant",
|
108
|
-
# content: "2004"
|
109
|
-
# },
|
110
|
-
# ]
|
111
|
-
#
|
112
|
-
# @param prompt [String] The prompt to generate a chat completion for
|
113
|
-
# @param messages [Array<Hash>] The messages that have been sent in the conversation
|
114
|
-
# @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"
|
115
|
-
# @param examples [Array<Hash>] Examples of messages to provide to the model. Useful for Few-Shot Prompting
|
116
|
-
# @param options [Hash] extra parameters passed to OpenAI::Client#chat
|
117
|
-
# @yield [Hash] Stream responses back one token at a time
|
118
|
-
# @return [Langchain::LLM::OpenAIResponse] Response object
|
119
|
-
#
|
120
|
-
def chat(prompt: "", messages: [], context: "", examples: [], **options, &block)
|
121
|
-
raise ArgumentError.new(":prompt or :messages argument is expected") if prompt.empty? && messages.empty?
|
122
|
-
|
123
|
-
parameters = compose_parameters @defaults[:chat_completion_model_name], options, &block
|
124
|
-
parameters[:messages] = compose_chat_messages(prompt: prompt, messages: messages, context: context, examples: examples)
|
125
|
-
|
126
|
-
if functions
|
127
|
-
parameters[:functions] = functions
|
128
|
-
else
|
129
|
-
parameters[:max_tokens] = validate_max_tokens(parameters[:messages], parameters[:model])
|
130
|
-
end
|
131
|
-
|
132
|
-
response = with_api_error_handling { chat_client.chat(parameters: parameters) }
|
133
|
-
|
134
|
-
return if block
|
135
|
-
|
136
|
-
Langchain::LLM::OpenAIResponse.new(response)
|
47
|
+
def chat(...)
|
48
|
+
@client = @chat_client
|
49
|
+
super(...)
|
137
50
|
end
|
138
51
|
end
|
139
52
|
end
|
data/lib/langchain/llm/base.rb
CHANGED
@@ -11,6 +11,7 @@ module Langchain::LLM
|
|
11
11
|
# - {Langchain::LLM::Azure}
|
12
12
|
# - {Langchain::LLM::Cohere}
|
13
13
|
# - {Langchain::LLM::GooglePalm}
|
14
|
+
# - {Langchain::LLM::GoogleVertexAi}
|
14
15
|
# - {Langchain::LLM::HuggingFace}
|
15
16
|
# - {Langchain::LLM::LlamaCpp}
|
16
17
|
# - {Langchain::LLM::OpenAI}
|
data/lib/langchain/llm/cohere.rb
CHANGED
@@ -62,17 +62,15 @@ module Langchain::LLM
|
|
62
62
|
|
63
63
|
default_params.merge!(params)
|
64
64
|
|
65
|
-
default_params[:max_tokens] = Langchain::Utils::TokenLength::CohereValidator.validate_max_tokens!(prompt, default_params[:model], client)
|
65
|
+
default_params[:max_tokens] = Langchain::Utils::TokenLength::CohereValidator.validate_max_tokens!(prompt, default_params[:model], llm: client)
|
66
66
|
|
67
67
|
response = client.generate(**default_params)
|
68
68
|
Langchain::LLM::CohereResponse.new response, model: @defaults[:completion_model_name]
|
69
69
|
end
|
70
70
|
|
71
|
-
#
|
72
|
-
def chat
|
73
|
-
|
74
|
-
::Langchain::Conversation::Response.new(response_text)
|
75
|
-
end
|
71
|
+
# TODO: Implement chat method: https://github.com/andreibondarev/cohere-ruby/issues/11
|
72
|
+
# def chat
|
73
|
+
# end
|
76
74
|
|
77
75
|
# Generate a summary in English for a given text
|
78
76
|
#
|
@@ -21,6 +21,9 @@ module Langchain::LLM
|
|
21
21
|
embeddings_model_name: "textembedding-gecko"
|
22
22
|
}.freeze
|
23
23
|
|
24
|
+
# TODO: Implement token length validation
|
25
|
+
# LENGTH_VALIDATOR = Langchain::Utils::TokenLength::...
|
26
|
+
|
24
27
|
# Google Cloud has a project id and a specific region of deployment.
|
25
28
|
# For GenAI-related things, a safe choice is us-central1.
|
26
29
|
attr_reader :project_id, :client, :region
|
@@ -135,15 +138,14 @@ module Langchain::LLM
|
|
135
138
|
)
|
136
139
|
end
|
137
140
|
|
138
|
-
def chat(...)
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
141
|
+
# def chat(...)
|
142
|
+
# https://cloud.google.com/vertex-ai/docs/samples/aiplatform-sdk-chathat
|
143
|
+
# Chat params: https://cloud.google.com/vertex-ai/docs/samples/aiplatform-sdk-chat
|
144
|
+
# \"temperature\": 0.3,\n"
|
145
|
+
# + " \"maxDecodeSteps\": 200,\n"
|
146
|
+
# + " \"topP\": 0.8,\n"
|
147
|
+
# + " \"topK\": 40\n"
|
148
|
+
# + "}";
|
149
|
+
# end
|
148
150
|
end
|
149
151
|
end
|
data/lib/langchain/llm/ollama.rb
CHANGED
@@ -5,21 +5,26 @@ module Langchain::LLM
|
|
5
5
|
# Available models: https://ollama.ai/library
|
6
6
|
#
|
7
7
|
# Usage:
|
8
|
-
# ollama = Langchain::LLM::Ollama.new(url: ENV["OLLAMA_URL"])
|
8
|
+
# ollama = Langchain::LLM::Ollama.new(url: ENV["OLLAMA_URL"], default_options: {})
|
9
9
|
#
|
10
10
|
class Ollama < Base
|
11
|
-
attr_reader :url
|
11
|
+
attr_reader :url, :defaults
|
12
12
|
|
13
13
|
DEFAULTS = {
|
14
|
-
temperature: 0.
|
14
|
+
temperature: 0.8,
|
15
15
|
completion_model_name: "llama2",
|
16
|
-
embeddings_model_name: "llama2"
|
16
|
+
embeddings_model_name: "llama2",
|
17
|
+
chat_completion_model_name: "llama2"
|
17
18
|
}.freeze
|
18
19
|
|
19
20
|
# Initialize the Ollama client
|
20
21
|
# @param url [String] The URL of the Ollama instance
|
21
|
-
|
22
|
+
# @param default_options [Hash] The default options to use
|
23
|
+
#
|
24
|
+
def initialize(url:, default_options: {})
|
25
|
+
depends_on "faraday"
|
22
26
|
@url = url
|
27
|
+
@defaults = DEFAULTS.merge(default_options)
|
23
28
|
end
|
24
29
|
|
25
30
|
#
|
@@ -27,32 +32,128 @@ module Langchain::LLM
|
|
27
32
|
#
|
28
33
|
# @param prompt [String] The prompt to complete
|
29
34
|
# @param model [String] The model to use
|
30
|
-
#
|
35
|
+
# For a list of valid parameters and values, see:
|
36
|
+
# https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values
|
31
37
|
# @return [Langchain::LLM::OllamaResponse] Response object
|
32
38
|
#
|
33
|
-
def complete(
|
34
|
-
|
39
|
+
def complete(
|
40
|
+
prompt:,
|
41
|
+
model: defaults[:completion_model_name],
|
42
|
+
images: nil,
|
43
|
+
format: nil,
|
44
|
+
system: nil,
|
45
|
+
template: nil,
|
46
|
+
context: nil,
|
47
|
+
stream: nil,
|
48
|
+
raw: nil,
|
49
|
+
mirostat: nil,
|
50
|
+
mirostat_eta: nil,
|
51
|
+
mirostat_tau: nil,
|
52
|
+
num_ctx: nil,
|
53
|
+
num_gqa: nil,
|
54
|
+
num_gpu: nil,
|
55
|
+
num_thread: nil,
|
56
|
+
repeat_last_n: nil,
|
57
|
+
repeat_penalty: nil,
|
58
|
+
temperature: defaults[:temperature],
|
59
|
+
seed: nil,
|
60
|
+
stop: nil,
|
61
|
+
tfs_z: nil,
|
62
|
+
num_predict: nil,
|
63
|
+
top_k: nil,
|
64
|
+
top_p: nil,
|
65
|
+
stop_sequences: nil,
|
66
|
+
&block
|
67
|
+
)
|
68
|
+
if stop_sequences
|
69
|
+
stop = stop_sequences
|
70
|
+
end
|
35
71
|
|
36
|
-
|
72
|
+
parameters = {
|
73
|
+
prompt: prompt,
|
74
|
+
model: model,
|
75
|
+
images: images,
|
76
|
+
format: format,
|
77
|
+
system: system,
|
78
|
+
template: template,
|
79
|
+
context: context,
|
80
|
+
stream: stream,
|
81
|
+
raw: raw
|
82
|
+
}.compact
|
83
|
+
|
84
|
+
llm_parameters = {
|
85
|
+
mirostat: mirostat,
|
86
|
+
mirostat_eta: mirostat_eta,
|
87
|
+
mirostat_tau: mirostat_tau,
|
88
|
+
num_ctx: num_ctx,
|
89
|
+
num_gqa: num_gqa,
|
90
|
+
num_gpu: num_gpu,
|
91
|
+
num_thread: num_thread,
|
92
|
+
repeat_last_n: repeat_last_n,
|
93
|
+
repeat_penalty: repeat_penalty,
|
94
|
+
temperature: temperature,
|
95
|
+
seed: seed,
|
96
|
+
stop: stop,
|
97
|
+
tfs_z: tfs_z,
|
98
|
+
num_predict: num_predict,
|
99
|
+
top_k: top_k,
|
100
|
+
top_p: top_p
|
101
|
+
}
|
102
|
+
|
103
|
+
parameters[:options] = llm_parameters.compact
|
104
|
+
|
105
|
+
response = ""
|
37
106
|
|
38
107
|
client.post("api/generate") do |req|
|
39
|
-
req.body =
|
40
|
-
req.body["prompt"] = prompt
|
41
|
-
req.body["model"] = model_name
|
42
|
-
|
43
|
-
req.body["options"] = options if options.any?
|
108
|
+
req.body = parameters
|
44
109
|
|
45
|
-
# TODO: Implement streaming support when a &block is passed in
|
46
110
|
req.options.on_data = proc do |chunk, size|
|
47
111
|
json_chunk = JSON.parse(chunk)
|
48
112
|
|
49
|
-
|
50
|
-
|
51
|
-
|
113
|
+
response += json_chunk.dig("response")
|
114
|
+
|
115
|
+
yield json_chunk, size if block
|
52
116
|
end
|
53
117
|
end
|
54
118
|
|
55
|
-
Langchain::LLM::OllamaResponse.new(response, model:
|
119
|
+
Langchain::LLM::OllamaResponse.new(response, model: parameters[:model])
|
120
|
+
end
|
121
|
+
|
122
|
+
# Generate a chat completion
|
123
|
+
#
|
124
|
+
# @param model [String] Model name
|
125
|
+
# @param messages [Array<Hash>] Array of messages
|
126
|
+
# @param format [String] Format to return a response in. Currently the only accepted value is `json`
|
127
|
+
# @param temperature [Float] The temperature to use
|
128
|
+
# @param template [String] The prompt template to use (overrides what is defined in the `Modelfile`)
|
129
|
+
# @param stream [Boolean] Streaming the response. If false the response will be returned as a single response object, rather than a stream of objects
|
130
|
+
#
|
131
|
+
# The message object has the following fields:
|
132
|
+
# role: the role of the message, either system, user or assistant
|
133
|
+
# content: the content of the message
|
134
|
+
# images (optional): a list of images to include in the message (for multimodal models such as llava)
|
135
|
+
def chat(
|
136
|
+
model: defaults[:chat_completion_model_name],
|
137
|
+
messages: [],
|
138
|
+
format: nil,
|
139
|
+
temperature: defaults[:temperature],
|
140
|
+
template: nil,
|
141
|
+
stream: false # TODO: Fix streaming.
|
142
|
+
)
|
143
|
+
parameters = {
|
144
|
+
model: model,
|
145
|
+
messages: messages,
|
146
|
+
format: format,
|
147
|
+
temperature: temperature,
|
148
|
+
template: template,
|
149
|
+
stream: stream
|
150
|
+
}.compact
|
151
|
+
|
152
|
+
response = client.post("api/chat") do |req|
|
153
|
+
req.body = parameters
|
154
|
+
end
|
155
|
+
|
156
|
+
Langchain::LLM::OllamaResponse.new(response.body, model: parameters[:model])
|
56
157
|
end
|
57
158
|
|
58
159
|
#
|
@@ -63,18 +164,57 @@ module Langchain::LLM
|
|
63
164
|
# @param options [Hash] The options to use
|
64
165
|
# @return [Langchain::LLM::OllamaResponse] Response object
|
65
166
|
#
|
66
|
-
def embed(
|
67
|
-
|
167
|
+
def embed(
|
168
|
+
text:,
|
169
|
+
model: defaults[:embeddings_model_name],
|
170
|
+
mirostat: nil,
|
171
|
+
mirostat_eta: nil,
|
172
|
+
mirostat_tau: nil,
|
173
|
+
num_ctx: nil,
|
174
|
+
num_gqa: nil,
|
175
|
+
num_gpu: nil,
|
176
|
+
num_thread: nil,
|
177
|
+
repeat_last_n: nil,
|
178
|
+
repeat_penalty: nil,
|
179
|
+
temperature: defaults[:temperature],
|
180
|
+
seed: nil,
|
181
|
+
stop: nil,
|
182
|
+
tfs_z: nil,
|
183
|
+
num_predict: nil,
|
184
|
+
top_k: nil,
|
185
|
+
top_p: nil
|
186
|
+
)
|
187
|
+
parameters = {
|
188
|
+
prompt: text,
|
189
|
+
model: model
|
190
|
+
}.compact
|
191
|
+
|
192
|
+
llm_parameters = {
|
193
|
+
mirostat: mirostat,
|
194
|
+
mirostat_eta: mirostat_eta,
|
195
|
+
mirostat_tau: mirostat_tau,
|
196
|
+
num_ctx: num_ctx,
|
197
|
+
num_gqa: num_gqa,
|
198
|
+
num_gpu: num_gpu,
|
199
|
+
num_thread: num_thread,
|
200
|
+
repeat_last_n: repeat_last_n,
|
201
|
+
repeat_penalty: repeat_penalty,
|
202
|
+
temperature: temperature,
|
203
|
+
seed: seed,
|
204
|
+
stop: stop,
|
205
|
+
tfs_z: tfs_z,
|
206
|
+
num_predict: num_predict,
|
207
|
+
top_k: top_k,
|
208
|
+
top_p: top_p
|
209
|
+
}
|
210
|
+
|
211
|
+
parameters[:options] = llm_parameters.compact
|
68
212
|
|
69
213
|
response = client.post("api/embeddings") do |req|
|
70
|
-
req.body =
|
71
|
-
req.body["prompt"] = text
|
72
|
-
req.body["model"] = model_name
|
73
|
-
|
74
|
-
req.body["options"] = options if options.any?
|
214
|
+
req.body = parameters
|
75
215
|
end
|
76
216
|
|
77
|
-
Langchain::LLM::OllamaResponse.new(response.body, model:
|
217
|
+
Langchain::LLM::OllamaResponse.new(response.body, model: parameters[:model])
|
78
218
|
end
|
79
219
|
|
80
220
|
private
|