langchainrb 0.8.2 → 0.9.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +53 -25
- 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/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/google_palm_response.rb +4 -0
- data/lib/langchain/llm/response/ollama_response.rb +4 -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 +2 -2
- data/lib/langchain/version.rb +1 -1
- data/lib/langchain.rb +2 -1
- metadata +8 -5
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/openai.rb
CHANGED
@@ -4,156 +4,170 @@ module Langchain::LLM
|
|
4
4
|
# LLM interface for OpenAI APIs: https://platform.openai.com/overview
|
5
5
|
#
|
6
6
|
# Gem requirements:
|
7
|
-
# gem "ruby-openai", "~> 6.
|
7
|
+
# gem "ruby-openai", "~> 6.3.0"
|
8
8
|
#
|
9
9
|
# Usage:
|
10
|
-
# openai = Langchain::LLM::OpenAI.new(
|
11
|
-
#
|
10
|
+
# openai = Langchain::LLM::OpenAI.new(
|
11
|
+
# api_key: ENV["OPENAI_API_KEY"],
|
12
|
+
# llm_options: {},
|
13
|
+
# default_options: {}
|
14
|
+
# )
|
12
15
|
class OpenAI < Base
|
13
16
|
DEFAULTS = {
|
14
17
|
n: 1,
|
15
18
|
temperature: 0.0,
|
16
|
-
completion_model_name: "gpt-3.5-turbo",
|
17
19
|
chat_completion_model_name: "gpt-3.5-turbo",
|
18
20
|
embeddings_model_name: "text-embedding-ada-002",
|
19
21
|
dimension: 1536
|
20
22
|
}.freeze
|
21
23
|
|
22
|
-
LEGACY_COMPLETION_MODELS = %w[
|
23
|
-
ada
|
24
|
-
babbage
|
25
|
-
curie
|
26
|
-
davinci
|
27
|
-
].freeze
|
28
|
-
|
29
24
|
LENGTH_VALIDATOR = Langchain::Utils::TokenLength::OpenAIValidator
|
30
25
|
|
31
|
-
|
26
|
+
attr_reader :defaults
|
32
27
|
|
28
|
+
# Initialize an OpenAI LLM instance
|
29
|
+
#
|
30
|
+
# @param api_key [String] The API key to use
|
31
|
+
# @param client_options [Hash] Options to pass to the OpenAI::Client constructor
|
33
32
|
def initialize(api_key:, llm_options: {}, default_options: {})
|
34
33
|
depends_on "ruby-openai", req: "openai"
|
35
34
|
|
36
35
|
@client = ::OpenAI::Client.new(access_token: api_key, **llm_options)
|
36
|
+
|
37
37
|
@defaults = DEFAULTS.merge(default_options)
|
38
38
|
end
|
39
39
|
|
40
|
-
#
|
41
40
|
# Generate an embedding for a given text
|
42
41
|
#
|
43
42
|
# @param text [String] The text to generate an embedding for
|
44
|
-
# @param
|
43
|
+
# @param model [String] ID of the model to use
|
44
|
+
# @param encoding_format [String] The format to return the embeddings in. Can be either float or base64.
|
45
|
+
# @param user [String] A unique identifier representing your end-user
|
45
46
|
# @return [Langchain::LLM::OpenAIResponse] Response object
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def embed(
|
48
|
+
text:,
|
49
|
+
model: defaults[:embeddings_model_name],
|
50
|
+
encoding_format: nil,
|
51
|
+
user: nil
|
52
|
+
)
|
53
|
+
raise ArgumentError.new("text argument is required") if text.empty?
|
54
|
+
raise ArgumentError.new("model argument is required") if model.empty?
|
55
|
+
raise ArgumentError.new("encoding_format must be either float or base64") if encoding_format && %w[float base64].include?(encoding_format)
|
56
|
+
|
57
|
+
parameters = {
|
58
|
+
input: text,
|
59
|
+
model: model
|
60
|
+
}
|
61
|
+
parameters[:encoding_format] = encoding_format if encoding_format
|
62
|
+
parameters[:user] = user if user
|
49
63
|
|
50
64
|
validate_max_tokens(text, parameters[:model])
|
51
65
|
|
52
66
|
response = with_api_error_handling do
|
53
|
-
client.embeddings(parameters: parameters
|
67
|
+
client.embeddings(parameters: parameters)
|
54
68
|
end
|
55
69
|
|
56
70
|
Langchain::LLM::OpenAIResponse.new(response)
|
57
71
|
end
|
58
72
|
|
59
|
-
#
|
73
|
+
# rubocop:disable Style/ArgumentsForwarding
|
60
74
|
# Generate a completion for a given prompt
|
61
75
|
#
|
62
76
|
# @param prompt [String] The prompt to generate a completion for
|
63
|
-
# @param params
|
64
|
-
# @return [Langchain::LLM::
|
65
|
-
#
|
77
|
+
# @param params [Hash] The parameters to pass to the `chat()` method
|
78
|
+
# @return [Langchain::LLM::OpenAIResponse] Response object
|
66
79
|
def complete(prompt:, **params)
|
67
|
-
|
68
|
-
|
69
|
-
return legacy_complete(prompt, parameters) if is_legacy_model?(parameters[:model])
|
70
|
-
|
71
|
-
parameters[:messages] = compose_chat_messages(prompt: prompt)
|
72
|
-
parameters[:max_tokens] = validate_max_tokens(parameters[:messages], parameters[:model], parameters[:max_tokens])
|
73
|
-
|
74
|
-
response = with_api_error_handling do
|
75
|
-
client.chat(parameters: parameters)
|
80
|
+
if params[:stop_sequences]
|
81
|
+
params[:stop] = params.delete(:stop_sequences)
|
76
82
|
end
|
77
|
-
|
78
|
-
|
83
|
+
# Should we still accept the `messages: []` parameter here?
|
84
|
+
messages = [{role: "user", content: prompt}]
|
85
|
+
chat(messages: messages, **params)
|
79
86
|
end
|
87
|
+
# rubocop:enable Style/ArgumentsForwarding
|
80
88
|
|
81
|
-
#
|
82
89
|
# Generate a chat completion for a given prompt or messages.
|
83
90
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
parameters =
|
129
|
-
parameters[:
|
91
|
+
# @param messages [Array<Hash>] List of messages comprising the conversation so far
|
92
|
+
# @param model [String] ID of the model to use
|
93
|
+
def chat(
|
94
|
+
messages: [],
|
95
|
+
model: defaults[:chat_completion_model_name],
|
96
|
+
frequency_penalty: nil,
|
97
|
+
logit_bias: nil,
|
98
|
+
logprobs: nil,
|
99
|
+
top_logprobs: nil,
|
100
|
+
max_tokens: nil,
|
101
|
+
n: defaults[:n],
|
102
|
+
presence_penalty: nil,
|
103
|
+
response_format: nil,
|
104
|
+
seed: nil,
|
105
|
+
stop: nil,
|
106
|
+
stream: nil,
|
107
|
+
temperature: defaults[:temperature],
|
108
|
+
top_p: nil,
|
109
|
+
tools: [],
|
110
|
+
tool_choice: nil,
|
111
|
+
user: nil,
|
112
|
+
&block
|
113
|
+
)
|
114
|
+
raise ArgumentError.new("messages argument is required") if messages.empty?
|
115
|
+
raise ArgumentError.new("model argument is required") if model.empty?
|
116
|
+
raise ArgumentError.new("'tool_choice' is only allowed when 'tools' are specified.") if tool_choice && tools.empty?
|
117
|
+
|
118
|
+
parameters = {
|
119
|
+
messages: messages,
|
120
|
+
model: model
|
121
|
+
}
|
122
|
+
parameters[:frequency_penalty] = frequency_penalty if frequency_penalty
|
123
|
+
parameters[:logit_bias] = logit_bias if logit_bias
|
124
|
+
parameters[:logprobs] = logprobs if logprobs
|
125
|
+
parameters[:top_logprobs] = top_logprobs if top_logprobs
|
126
|
+
# TODO: Fix max_tokens validation to account for tools/functions
|
127
|
+
parameters[:max_tokens] = max_tokens if max_tokens # || validate_max_tokens(parameters[:messages], parameters[:model])
|
128
|
+
parameters[:n] = n if n
|
129
|
+
parameters[:presence_penalty] = presence_penalty if presence_penalty
|
130
|
+
parameters[:response_format] = response_format if response_format
|
131
|
+
parameters[:seed] = seed if seed
|
132
|
+
parameters[:stop] = stop if stop
|
133
|
+
parameters[:stream] = stream if stream
|
134
|
+
parameters[:temperature] = temperature if temperature
|
135
|
+
parameters[:top_p] = top_p if top_p
|
136
|
+
parameters[:tools] = tools if tools.any?
|
137
|
+
parameters[:tool_choice] = tool_choice if tool_choice
|
138
|
+
parameters[:user] = user if user
|
139
|
+
|
140
|
+
# TODO: Clean this part up
|
141
|
+
if block
|
142
|
+
@response_chunks = []
|
143
|
+
parameters[:stream] = proc do |chunk, _bytesize|
|
144
|
+
chunk_content = chunk.dig("choices", 0)
|
145
|
+
@response_chunks << chunk
|
146
|
+
yield chunk_content
|
147
|
+
end
|
148
|
+
end
|
130
149
|
|
131
|
-
|
132
|
-
parameters
|
133
|
-
else
|
134
|
-
parameters[:max_tokens] = validate_max_tokens(parameters[:messages], parameters[:model], parameters[:max_tokens])
|
150
|
+
response = with_api_error_handling do
|
151
|
+
client.chat(parameters: parameters)
|
135
152
|
end
|
136
153
|
|
137
|
-
response = with_api_error_handling { client.chat(parameters: parameters) }
|
138
154
|
response = response_from_chunks if block
|
139
155
|
reset_response_chunks
|
156
|
+
|
140
157
|
Langchain::LLM::OpenAIResponse.new(response)
|
141
158
|
end
|
142
159
|
|
143
|
-
#
|
144
160
|
# Generate a summary for a given text
|
145
161
|
#
|
146
162
|
# @param text [String] The text to generate a summary for
|
147
163
|
# @return [String] The summary
|
148
|
-
#
|
149
164
|
def summarize(text:)
|
150
165
|
prompt_template = Langchain::Prompt.load_from_path(
|
151
166
|
file_path: Langchain.root.join("langchain/llm/prompts/summarize_template.yaml")
|
152
167
|
)
|
153
168
|
prompt = prompt_template.format(text: text)
|
154
169
|
|
155
|
-
complete(prompt: prompt
|
156
|
-
# Should this return a Langchain::LLM::OpenAIResponse as well?
|
170
|
+
complete(prompt: prompt)
|
157
171
|
end
|
158
172
|
|
159
173
|
private
|
@@ -164,71 +178,6 @@ module Langchain::LLM
|
|
164
178
|
@response_chunks = []
|
165
179
|
end
|
166
180
|
|
167
|
-
def is_legacy_model?(model)
|
168
|
-
LEGACY_COMPLETION_MODELS.any? { |legacy_model| model.include?(legacy_model) }
|
169
|
-
end
|
170
|
-
|
171
|
-
def legacy_complete(prompt, parameters)
|
172
|
-
Langchain.logger.warn "DEPRECATION WARNING: The model #{parameters[:model]} is deprecated. Please use gpt-3.5-turbo instead. Details: https://platform.openai.com/docs/deprecations/2023-07-06-gpt-and-embeddings"
|
173
|
-
|
174
|
-
parameters[:prompt] = prompt
|
175
|
-
parameters[:max_tokens] = validate_max_tokens(prompt, parameters[:model])
|
176
|
-
|
177
|
-
response = with_api_error_handling do
|
178
|
-
client.completions(parameters: parameters)
|
179
|
-
end
|
180
|
-
response.dig("choices", 0, "text")
|
181
|
-
end
|
182
|
-
|
183
|
-
def compose_parameters(model, params, &block)
|
184
|
-
default_params = {model: model, temperature: @defaults[:temperature], n: @defaults[:n]}
|
185
|
-
default_params[:stop] = params.delete(:stop_sequences) if params[:stop_sequences]
|
186
|
-
parameters = default_params.merge(params)
|
187
|
-
|
188
|
-
if block
|
189
|
-
@response_chunks = []
|
190
|
-
parameters[:stream] = proc do |chunk, _bytesize|
|
191
|
-
chunk_content = chunk.dig("choices", 0)
|
192
|
-
@response_chunks << chunk
|
193
|
-
yield chunk_content
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
parameters
|
198
|
-
end
|
199
|
-
|
200
|
-
def compose_chat_messages(prompt:, messages: [], context: "", examples: [])
|
201
|
-
history = []
|
202
|
-
|
203
|
-
history.concat transform_messages(examples) unless examples.empty?
|
204
|
-
|
205
|
-
history.concat transform_messages(messages) unless messages.empty?
|
206
|
-
|
207
|
-
unless context.nil? || context.empty?
|
208
|
-
history.reject! { |message| message[:role] == "system" }
|
209
|
-
history.prepend({role: "system", content: context})
|
210
|
-
end
|
211
|
-
|
212
|
-
unless prompt.empty?
|
213
|
-
if history.last && history.last[:role] == "user"
|
214
|
-
history.last[:content] += "\n#{prompt}"
|
215
|
-
else
|
216
|
-
history.append({role: "user", content: prompt})
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
history
|
221
|
-
end
|
222
|
-
|
223
|
-
def transform_messages(messages)
|
224
|
-
messages.map do |message|
|
225
|
-
{
|
226
|
-
role: message[:role],
|
227
|
-
content: message[:content]
|
228
|
-
}
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
181
|
def with_api_error_handling
|
233
182
|
response = yield
|
234
183
|
return if response.empty?
|
@@ -239,12 +188,7 @@ module Langchain::LLM
|
|
239
188
|
end
|
240
189
|
|
241
190
|
def validate_max_tokens(messages, model, max_tokens = nil)
|
242
|
-
LENGTH_VALIDATOR.validate_max_tokens!(messages, model, max_tokens: max_tokens)
|
243
|
-
end
|
244
|
-
|
245
|
-
def extract_response(response)
|
246
|
-
results = response.dig("choices").map { |choice| choice.dig("message", "content") }
|
247
|
-
(results.size == 1) ? results.first : results
|
191
|
+
LENGTH_VALIDATOR.validate_max_tokens!(messages, model, max_tokens: max_tokens, llm: self)
|
248
192
|
end
|
249
193
|
|
250
194
|
def response_from_chunks
|
@@ -77,12 +77,6 @@ module Langchain::LLM
|
|
77
77
|
Langchain::LLM::ReplicateResponse.new(response, model: @defaults[:completion_model_name])
|
78
78
|
end
|
79
79
|
|
80
|
-
# Cohere does not have a dedicated chat endpoint, so instead we call `complete()`
|
81
|
-
def chat(...)
|
82
|
-
response_text = complete(...)
|
83
|
-
::Langchain::Conversation::Response.new(response_text)
|
84
|
-
end
|
85
|
-
|
86
80
|
#
|
87
81
|
# Generate a summary for a given text
|
88
82
|
#
|
@@ -16,10 +16,18 @@ module Langchain::LLM
|
|
16
16
|
completions&.dig(0, "message", "content")
|
17
17
|
end
|
18
18
|
|
19
|
+
def role
|
20
|
+
completions&.dig(0, "message", "role")
|
21
|
+
end
|
22
|
+
|
19
23
|
def chat_completion
|
20
24
|
completion
|
21
25
|
end
|
22
26
|
|
27
|
+
def tool_calls
|
28
|
+
chat_completions&.dig(0, "message", "tool_calls")
|
29
|
+
end
|
30
|
+
|
23
31
|
def embedding
|
24
32
|
embeddings&.first
|
25
33
|
end
|
data/lib/langchain/tool/base.rb
CHANGED
@@ -91,6 +91,30 @@ module Langchain::Tool
|
|
91
91
|
new.execute(input: input)
|
92
92
|
end
|
93
93
|
|
94
|
+
# Returns the tool as an OpenAI tool
|
95
|
+
#
|
96
|
+
# @return [Hash] tool as an OpenAI tool
|
97
|
+
def to_openai_tool
|
98
|
+
# TODO: This is hardcoded to def execute(input:) found in each tool, needs to be dynamic.
|
99
|
+
{
|
100
|
+
type: "function",
|
101
|
+
function: {
|
102
|
+
name: name,
|
103
|
+
description: description,
|
104
|
+
parameters: {
|
105
|
+
type: "object",
|
106
|
+
properties: {
|
107
|
+
input: {
|
108
|
+
type: "string",
|
109
|
+
description: "Input to the tool"
|
110
|
+
}
|
111
|
+
},
|
112
|
+
required: ["input"]
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
94
118
|
#
|
95
119
|
# Executes the tool and returns the answer
|
96
120
|
#
|
@@ -17,10 +17,7 @@ module Langchain::Tool
|
|
17
17
|
description <<~DESC
|
18
18
|
A wrapper around SerpApi's Google Search API.
|
19
19
|
|
20
|
-
Useful for when you need to answer questions about current events.
|
21
|
-
Always one of the first options when you need to find information on internet.
|
22
|
-
|
23
|
-
Input should be a search query.
|
20
|
+
Useful for when you need to answer questions about current events. Always one of the first options when you need to find information on internet. Input should be a search query.
|
24
21
|
DESC
|
25
22
|
|
26
23
|
attr_reader :api_key
|
@@ -22,8 +22,8 @@ module Langchain
|
|
22
22
|
# @param model_name [String] The model name to validate against
|
23
23
|
# @return [Integer] The token length of the text
|
24
24
|
#
|
25
|
-
def self.token_length(text, model_name,
|
26
|
-
res =
|
25
|
+
def self.token_length(text, model_name, options = {})
|
26
|
+
res = options[:llm].tokenize(text)
|
27
27
|
res.dig(:tokens).length
|
28
28
|
end
|
29
29
|
|
@@ -30,8 +30,8 @@ module Langchain
|
|
30
30
|
# @param model_name [String] The model name to validate against
|
31
31
|
# @return [Integer] The token length of the text
|
32
32
|
#
|
33
|
-
def self.token_length(text, model_name,
|
34
|
-
res =
|
33
|
+
def self.token_length(text, model_name, options = {})
|
34
|
+
res = options[:llm].tokenize(text: text)
|
35
35
|
res["tokens"].length
|
36
36
|
end
|
37
37
|
|
@@ -35,7 +35,7 @@ module Langchain
|
|
35
35
|
# @option options [Langchain::LLM:GooglePalm] :llm The Langchain::LLM:GooglePalm instance
|
36
36
|
# @return [Integer] The token length of the text
|
37
37
|
#
|
38
|
-
def self.token_length(text, model_name = "chat-bison-001", options)
|
38
|
+
def self.token_length(text, model_name = "chat-bison-001", options = {})
|
39
39
|
response = options[:llm].client.count_message_tokens(model: model_name, prompt: text)
|
40
40
|
|
41
41
|
raise Langchain::LLM::ApiError.new(response["error"]["message"]) unless response["error"].nil?
|
@@ -43,7 +43,7 @@ module Langchain
|
|
43
43
|
response.dig("tokenCount")
|
44
44
|
end
|
45
45
|
|
46
|
-
def self.token_length_from_messages(messages, model_name, options)
|
46
|
+
def self.token_length_from_messages(messages, model_name, options = {})
|
47
47
|
messages.sum { |message| token_length(message.to_json, model_name, options) }
|
48
48
|
end
|
49
49
|
|
@@ -93,10 +93,10 @@ module Langchain
|
|
93
93
|
tokens_per_message = 4 # every message follows {role/name}\n{content}\n
|
94
94
|
tokens_per_name = -1 # if there's a name, the role is omitted
|
95
95
|
elsif model_name.include?("gpt-3.5-turbo")
|
96
|
-
puts "Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613."
|
96
|
+
# puts "Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613."
|
97
97
|
return token_length_from_messages(messages, "gpt-3.5-turbo-0613", options)
|
98
98
|
elsif model_name.include?("gpt-4")
|
99
|
-
puts "Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613."
|
99
|
+
# puts "Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613."
|
100
100
|
return token_length_from_messages(messages, "gpt-4-0613", options)
|
101
101
|
else
|
102
102
|
raise NotImplementedError.new(
|
data/lib/langchain/version.rb
CHANGED
data/lib/langchain.rb
CHANGED
@@ -24,6 +24,7 @@ loader.inflector.inflect(
|
|
24
24
|
"sql_query_agent" => "SQLQueryAgent"
|
25
25
|
)
|
26
26
|
loader.collapse("#{__dir__}/langchain/llm/response")
|
27
|
+
loader.collapse("#{__dir__}/langchain/assistants")
|
27
28
|
loader.setup
|
28
29
|
|
29
30
|
# Langchain.rb a is library for building LLM-backed Ruby applications. It is an abstraction layer that sits on top of the emerging AI-related tools that makes it easy for developers to consume and string those services together.
|
@@ -82,7 +83,7 @@ module Langchain
|
|
82
83
|
attr_reader :root
|
83
84
|
end
|
84
85
|
|
85
|
-
self.logger ||= ::Logger.new($stdout, level: :
|
86
|
+
self.logger ||= ::Logger.new($stdout, level: :debug)
|
86
87
|
|
87
88
|
@root = Pathname.new(__dir__)
|
88
89
|
|