langchainrb 0.12.0 → 0.12.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 +7 -0
- data/lib/langchain/llm/anthropic.rb +27 -49
- data/lib/langchain/llm/aws_bedrock.rb +30 -34
- data/lib/langchain/llm/azure.rb +6 -0
- data/lib/langchain/llm/base.rb +18 -0
- data/lib/langchain/llm/cohere.rb +38 -6
- data/lib/langchain/llm/mistral_ai.rb +10 -19
- data/lib/langchain/llm/ollama.rb +23 -27
- data/lib/langchain/llm/openai.rb +20 -48
- data/lib/langchain/llm/parameters/chat.rb +51 -0
- data/lib/langchain/llm/response/base_response.rb +2 -2
- data/lib/langchain/llm/response/cohere_response.rb +16 -0
- data/lib/langchain/llm/unified_parameters.rb +98 -0
- data/lib/langchain/loader.rb +6 -0
- data/lib/langchain/tool/base.rb +5 -5
- data/lib/langchain/utils/token_length/openai_validator.rb +6 -1
- data/lib/langchain/version.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f106f178a5641f17ca723eec7272d120fbdd0e3046e44152eaf575af2985724
|
4
|
+
data.tar.gz: 417d5b671a6783d0854c05c43871b1e931133eaf65e6d39ac6ac4989a0124e36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 184b139d3e9d54fcd42665e25692d9fdb14e92c3d0bb23713647dfa2f1a87854215b13cc9573f10872d3e2e09d042e8c05640356276bc69a32423119e99c129b
|
7
|
+
data.tar.gz: 4503a8498018b53a9068345186efe03a72da4340d82a0f7806d4007e220c748814ab2da49194e09fd11ef33de3a35f38048e835dd43cee2c0b967bb810bfb512
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.12.1] - 2024-05-13
|
4
|
+
- Langchain::LLM::Ollama now uses `llama3` by default
|
5
|
+
- Langchain::LLM::Anthropic#complete() now uses `claude-2.1` by default
|
6
|
+
- Updated with new OpenAI models, including `gpt-4o`
|
7
|
+
- New `Langchain::LLM::Cohere#chat()` method.
|
8
|
+
- Introducing `UnifiedParameters` to unify parameters across LLM classes
|
9
|
+
|
3
10
|
## [0.12.0] - 2024-04-22
|
4
11
|
- [BREAKING] Rename `dimension` parameter to `dimensions` everywhere
|
5
12
|
|
@@ -13,7 +13,7 @@ module Langchain::LLM
|
|
13
13
|
class Anthropic < Base
|
14
14
|
DEFAULTS = {
|
15
15
|
temperature: 0.0,
|
16
|
-
completion_model_name: "claude-2",
|
16
|
+
completion_model_name: "claude-2.1",
|
17
17
|
chat_completion_model_name: "claude-3-sonnet-20240229",
|
18
18
|
max_tokens_to_sample: 256
|
19
19
|
}.freeze
|
@@ -32,6 +32,15 @@ module Langchain::LLM
|
|
32
32
|
|
33
33
|
@client = ::Anthropic::Client.new(access_token: api_key, **llm_options)
|
34
34
|
@defaults = DEFAULTS.merge(default_options)
|
35
|
+
chat_parameters.update(
|
36
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
37
|
+
temperature: {default: @defaults[:temperature]},
|
38
|
+
max_tokens: {default: @defaults[:max_tokens_to_sample]},
|
39
|
+
metadata: {},
|
40
|
+
system: {}
|
41
|
+
)
|
42
|
+
chat_parameters.ignore(:n, :user)
|
43
|
+
chat_parameters.remap(stop: :stop_sequences)
|
35
44
|
end
|
36
45
|
|
37
46
|
# Generate a completion for a given prompt
|
@@ -72,66 +81,35 @@ module Langchain::LLM
|
|
72
81
|
parameters[:metadata] = metadata if metadata
|
73
82
|
parameters[:stream] = stream if stream
|
74
83
|
|
75
|
-
# TODO: Implement token length validator for Anthropic
|
76
|
-
# parameters[:max_tokens_to_sample] = validate_max_tokens(prompt, parameters[:completion_model_name])
|
77
|
-
|
78
84
|
response = client.complete(parameters: parameters)
|
79
85
|
Langchain::LLM::AnthropicResponse.new(response)
|
80
86
|
end
|
81
87
|
|
82
88
|
# Generate a chat completion for given messages
|
83
89
|
#
|
84
|
-
# @param
|
85
|
-
# @
|
86
|
-
# @
|
87
|
-
# @
|
88
|
-
# @
|
89
|
-
# @
|
90
|
-
# @
|
91
|
-
# @
|
92
|
-
# @
|
93
|
-
# @
|
94
|
-
# @
|
90
|
+
# @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
|
91
|
+
# @option params [Array<String>] :messages Input messages
|
92
|
+
# @option params [String] :model The model that will complete your prompt
|
93
|
+
# @option params [Integer] :max_tokens Maximum number of tokens to generate before stopping
|
94
|
+
# @option params [Hash] :metadata Object describing metadata about the request
|
95
|
+
# @option params [Array<String>] :stop_sequences Custom text sequences that will cause the model to stop generating
|
96
|
+
# @option params [Boolean] :stream Whether to incrementally stream the response using server-sent events
|
97
|
+
# @option params [String] :system System prompt
|
98
|
+
# @option params [Float] :temperature Amount of randomness injected into the response
|
99
|
+
# @option params [Array<String>] :tools Definitions of tools that the model may use
|
100
|
+
# @option params [Integer] :top_k Only sample from the top K options for each subsequent token
|
101
|
+
# @option params [Float] :top_p Use nucleus sampling.
|
95
102
|
# @return [Langchain::LLM::AnthropicResponse] The chat completion
|
96
|
-
def chat(
|
97
|
-
|
98
|
-
model: @defaults[:chat_completion_model_name],
|
99
|
-
max_tokens: @defaults[:max_tokens_to_sample],
|
100
|
-
metadata: nil,
|
101
|
-
stop_sequences: nil,
|
102
|
-
stream: nil,
|
103
|
-
system: nil,
|
104
|
-
temperature: @defaults[:temperature],
|
105
|
-
tools: [],
|
106
|
-
top_k: nil,
|
107
|
-
top_p: nil
|
108
|
-
)
|
109
|
-
raise ArgumentError.new("messages argument is required") if messages.empty?
|
110
|
-
raise ArgumentError.new("model argument is required") if model.empty?
|
111
|
-
raise ArgumentError.new("max_tokens argument is required") if max_tokens.nil?
|
103
|
+
def chat(params = {})
|
104
|
+
parameters = chat_parameters.to_params(params)
|
112
105
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
max_tokens: max_tokens,
|
117
|
-
temperature: temperature
|
118
|
-
}
|
119
|
-
parameters[:metadata] = metadata if metadata
|
120
|
-
parameters[:stop_sequences] = stop_sequences if stop_sequences
|
121
|
-
parameters[:stream] = stream if stream
|
122
|
-
parameters[:system] = system if system
|
123
|
-
parameters[:tools] = tools if tools.any?
|
124
|
-
parameters[:top_k] = top_k if top_k
|
125
|
-
parameters[:top_p] = top_p if top_p
|
106
|
+
raise ArgumentError.new("messages argument is required") if Array(parameters[:messages]).empty?
|
107
|
+
raise ArgumentError.new("model argument is required") if parameters[:model].empty?
|
108
|
+
raise ArgumentError.new("max_tokens argument is required") if parameters[:max_tokens].nil?
|
126
109
|
|
127
110
|
response = client.messages(parameters: parameters)
|
128
111
|
|
129
112
|
Langchain::LLM::AnthropicResponse.new(response)
|
130
113
|
end
|
131
|
-
|
132
|
-
# TODO: Implement token length validator for Anthropic
|
133
|
-
# def validate_max_tokens(messages, model)
|
134
|
-
# LENGTH_VALIDATOR.validate_max_tokens!(messages, model)
|
135
|
-
# end
|
136
114
|
end
|
137
115
|
end
|
@@ -59,6 +59,17 @@ module Langchain::LLM
|
|
59
59
|
@defaults = DEFAULTS.merge(default_options)
|
60
60
|
.merge(completion_model_name: completion_model)
|
61
61
|
.merge(embedding_model_name: embedding_model)
|
62
|
+
|
63
|
+
chat_parameters.update(
|
64
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
65
|
+
temperature: {},
|
66
|
+
max_tokens: {default: @defaults[:max_tokens_to_sample]},
|
67
|
+
metadata: {},
|
68
|
+
system: {},
|
69
|
+
anthropic_version: {default: "bedrock-2023-05-31"}
|
70
|
+
)
|
71
|
+
chat_parameters.ignore(:n, :user)
|
72
|
+
chat_parameters.remap(stop: :stop_sequences)
|
62
73
|
end
|
63
74
|
|
64
75
|
#
|
@@ -113,43 +124,28 @@ module Langchain::LLM
|
|
113
124
|
# Generate a chat completion for a given prompt
|
114
125
|
# Currently only configured to work with the Anthropic provider and
|
115
126
|
# the claude-3 model family
|
116
|
-
#
|
117
|
-
# @param
|
118
|
-
# @
|
119
|
-
# @
|
120
|
-
# @
|
121
|
-
# @
|
122
|
-
# @
|
123
|
-
# @
|
127
|
+
#
|
128
|
+
# @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
|
129
|
+
# @option params [Array<String>] :messages The messages to generate a completion for
|
130
|
+
# @option params [String] :system The system prompt to provide instructions
|
131
|
+
# @option params [String] :model The model to use for completion defaults to @defaults[:chat_completion_model_name]
|
132
|
+
# @option params [Integer] :max_tokens The maximum number of tokens to generate defaults to @defaults[:max_tokens_to_sample]
|
133
|
+
# @option params [Array<String>] :stop The stop sequences to use for completion
|
134
|
+
# @option params [Array<String>] :stop_sequences The stop sequences to use for completion
|
135
|
+
# @option params [Float] :temperature The temperature to use for completion
|
136
|
+
# @option params [Float] :top_p Use nucleus sampling.
|
137
|
+
# @option params [Integer] :top_k Only sample from the top K options for each subsequent token
|
124
138
|
# @return [Langchain::LLM::AnthropicMessagesResponse] Response object
|
125
|
-
def chat(
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
temperature: nil,
|
132
|
-
top_p: nil,
|
133
|
-
top_k: nil
|
134
|
-
)
|
135
|
-
raise ArgumentError.new("messages argument is required") if messages.empty?
|
136
|
-
|
137
|
-
raise "Model #{model} does not support chat completions." unless Langchain::LLM::AwsBedrock::SUPPORTED_CHAT_COMPLETION_PROVIDERS.include?(completion_provider)
|
138
|
-
|
139
|
-
inference_parameters = {
|
140
|
-
messages: messages,
|
141
|
-
max_tokens: max_tokens,
|
142
|
-
anthropic_version: @defaults[:anthropic_version]
|
143
|
-
}
|
144
|
-
inference_parameters[:system] = system if system
|
145
|
-
inference_parameters[:stop_sequences] = stop_sequences if stop_sequences
|
146
|
-
inference_parameters[:temperature] = temperature if temperature
|
147
|
-
inference_parameters[:top_p] = top_p if top_p
|
148
|
-
inference_parameters[:top_k] = top_k if top_k
|
139
|
+
def chat(params = {})
|
140
|
+
parameters = chat_parameters.to_params(params)
|
141
|
+
|
142
|
+
raise ArgumentError.new("messages argument is required") if Array(parameters[:messages]).empty?
|
143
|
+
|
144
|
+
raise "Model #{parameters[:model]} does not support chat completions." unless Langchain::LLM::AwsBedrock::SUPPORTED_CHAT_COMPLETION_PROVIDERS.include?(completion_provider)
|
149
145
|
|
150
146
|
response = client.invoke_model({
|
151
|
-
model_id: model,
|
152
|
-
body:
|
147
|
+
model_id: parameters[:model],
|
148
|
+
body: parameters.except(:model).to_json,
|
153
149
|
content_type: "application/json",
|
154
150
|
accept: "application/json"
|
155
151
|
})
|
data/lib/langchain/llm/azure.rb
CHANGED
data/lib/langchain/llm/base.rb
CHANGED
@@ -24,6 +24,15 @@ module Langchain::LLM
|
|
24
24
|
# A client for communicating with the LLM
|
25
25
|
attr_reader :client
|
26
26
|
|
27
|
+
# Ensuring backward compatibility after https://github.com/patterns-ai-core/langchainrb/pull/586
|
28
|
+
# TODO: Delete this method later
|
29
|
+
def default_dimension
|
30
|
+
default_dimensions
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the number of vector dimensions used by DEFAULTS[:chat_completion_model_name]
|
34
|
+
#
|
35
|
+
# @return [Integer] Vector dimensions
|
27
36
|
def default_dimensions
|
28
37
|
self.class.const_get(:DEFAULTS).dig(:dimensions)
|
29
38
|
end
|
@@ -61,5 +70,14 @@ module Langchain::LLM
|
|
61
70
|
def summarize(...)
|
62
71
|
raise NotImplementedError, "#{self.class.name} does not support summarization"
|
63
72
|
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Returns an instance of Langchain::LLM::Parameters::Chat
|
76
|
+
#
|
77
|
+
def chat_parameters(params = {})
|
78
|
+
@chat_parameters ||= Langchain::LLM::Parameters::Chat.new(
|
79
|
+
parameters: params
|
80
|
+
)
|
81
|
+
end
|
64
82
|
end
|
65
83
|
end
|
data/lib/langchain/llm/cohere.rb
CHANGED
@@ -8,22 +8,34 @@ module Langchain::LLM
|
|
8
8
|
# gem "cohere-ruby", "~> 0.9.6"
|
9
9
|
#
|
10
10
|
# Usage:
|
11
|
-
#
|
11
|
+
# llm = Langchain::LLM::Cohere.new(api_key: ENV["COHERE_API_KEY"])
|
12
12
|
#
|
13
13
|
class Cohere < Base
|
14
14
|
DEFAULTS = {
|
15
15
|
temperature: 0.0,
|
16
16
|
completion_model_name: "command",
|
17
|
+
chat_completion_model_name: "command-r-plus",
|
17
18
|
embeddings_model_name: "small",
|
18
19
|
dimensions: 1024,
|
19
20
|
truncate: "START"
|
20
21
|
}.freeze
|
21
22
|
|
22
|
-
def initialize(api_key
|
23
|
+
def initialize(api_key:, default_options: {})
|
23
24
|
depends_on "cohere-ruby", req: "cohere"
|
24
25
|
|
25
|
-
@client = ::Cohere::Client.new(api_key)
|
26
|
+
@client = ::Cohere::Client.new(api_key: api_key)
|
26
27
|
@defaults = DEFAULTS.merge(default_options)
|
28
|
+
chat_parameters.update(
|
29
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
30
|
+
temperature: {default: @defaults[:temperature]}
|
31
|
+
)
|
32
|
+
chat_parameters.remap(
|
33
|
+
system: :preamble,
|
34
|
+
messages: :chat_history,
|
35
|
+
stop: :stop_sequences,
|
36
|
+
top_k: :k,
|
37
|
+
top_p: :p
|
38
|
+
)
|
27
39
|
end
|
28
40
|
|
29
41
|
#
|
@@ -68,9 +80,29 @@ module Langchain::LLM
|
|
68
80
|
Langchain::LLM::CohereResponse.new response, model: @defaults[:completion_model_name]
|
69
81
|
end
|
70
82
|
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
83
|
+
# Generate a chat completion for given messages
|
84
|
+
#
|
85
|
+
# @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
|
86
|
+
# @option params [Array<String>] :messages Input messages
|
87
|
+
# @option params [String] :model The model that will complete your prompt
|
88
|
+
# @option params [Integer] :max_tokens Maximum number of tokens to generate before stopping
|
89
|
+
# @option params [Array<String>] :stop Custom text sequences that will cause the model to stop generating
|
90
|
+
# @option params [Boolean] :stream Whether to incrementally stream the response using server-sent events
|
91
|
+
# @option params [String] :system System prompt
|
92
|
+
# @option params [Float] :temperature Amount of randomness injected into the response
|
93
|
+
# @option params [Array<String>] :tools Definitions of tools that the model may use
|
94
|
+
# @option params [Integer] :top_k Only sample from the top K options for each subsequent token
|
95
|
+
# @option params [Float] :top_p Use nucleus sampling.
|
96
|
+
# @return [Langchain::LLM::CohereResponse] The chat completion
|
97
|
+
def chat(params = {})
|
98
|
+
raise ArgumentError.new("messages argument is required") if Array(params[:messages]).empty?
|
99
|
+
|
100
|
+
parameters = chat_parameters.to_params(params)
|
101
|
+
|
102
|
+
response = client.chat(**parameters)
|
103
|
+
|
104
|
+
Langchain::LLM::CohereResponse.new(response)
|
105
|
+
end
|
74
106
|
|
75
107
|
# Generate a summary in English for a given text
|
76
108
|
#
|
@@ -23,28 +23,19 @@ module Langchain::LLM
|
|
23
23
|
)
|
24
24
|
|
25
25
|
@defaults = DEFAULTS.merge(default_options)
|
26
|
+
chat_parameters.update(
|
27
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
28
|
+
n: {default: @defaults[:n]},
|
29
|
+
safe_prompt: {}
|
30
|
+
)
|
31
|
+
chat_parameters.remap(seed: :random_seed)
|
32
|
+
chat_parameters.ignore(:n, :top_k)
|
26
33
|
end
|
27
34
|
|
28
|
-
def chat(
|
29
|
-
|
30
|
-
model: defaults[:chat_completion_model_name],
|
31
|
-
temperature: nil,
|
32
|
-
top_p: nil,
|
33
|
-
max_tokens: nil,
|
34
|
-
safe_prompt: nil,
|
35
|
-
random_seed: nil
|
36
|
-
)
|
37
|
-
params = {
|
38
|
-
messages: messages,
|
39
|
-
model: model
|
40
|
-
}
|
41
|
-
params[:temperature] = temperature if temperature
|
42
|
-
params[:top_p] = top_p if top_p
|
43
|
-
params[:max_tokens] = max_tokens if max_tokens
|
44
|
-
params[:safe_prompt] = safe_prompt if safe_prompt
|
45
|
-
params[:random_seed] = random_seed if random_seed
|
35
|
+
def chat(params = {})
|
36
|
+
parameters = chat_parameters.to_params(params)
|
46
37
|
|
47
|
-
response = client.chat_completions(
|
38
|
+
response = client.chat_completions(parameters)
|
48
39
|
|
49
40
|
Langchain::LLM::MistralAIResponse.new(response.to_h)
|
50
41
|
end
|
data/lib/langchain/llm/ollama.rb
CHANGED
@@ -7,22 +7,24 @@ module Langchain::LLM
|
|
7
7
|
# Available models: https://ollama.ai/library
|
8
8
|
#
|
9
9
|
# Usage:
|
10
|
-
#
|
10
|
+
# llm = Langchain::LLM::Ollama.new
|
11
|
+
# llm = Langchain::LLM::Ollama.new(url: ENV["OLLAMA_URL"], default_options: {})
|
11
12
|
#
|
12
13
|
class Ollama < Base
|
13
14
|
attr_reader :url, :defaults
|
14
15
|
|
15
16
|
DEFAULTS = {
|
16
17
|
temperature: 0.8,
|
17
|
-
completion_model_name: "
|
18
|
-
embeddings_model_name: "
|
19
|
-
chat_completion_model_name: "
|
18
|
+
completion_model_name: "llama3",
|
19
|
+
embeddings_model_name: "llama3",
|
20
|
+
chat_completion_model_name: "llama3"
|
20
21
|
}.freeze
|
21
22
|
|
22
23
|
EMBEDDING_SIZES = {
|
23
24
|
codellama: 4_096,
|
24
25
|
"dolphin-mixtral": 4_096,
|
25
26
|
llama2: 4_096,
|
27
|
+
llama3: 4_096,
|
26
28
|
llava: 4_096,
|
27
29
|
mistral: 4_096,
|
28
30
|
"mistral-openorca": 4_096,
|
@@ -33,10 +35,17 @@ module Langchain::LLM
|
|
33
35
|
# @param url [String] The URL of the Ollama instance
|
34
36
|
# @param default_options [Hash] The default options to use
|
35
37
|
#
|
36
|
-
def initialize(url
|
38
|
+
def initialize(url: "http://localhost:11434", default_options: {})
|
37
39
|
depends_on "faraday"
|
38
40
|
@url = url
|
39
41
|
@defaults = DEFAULTS.deep_merge(default_options)
|
42
|
+
chat_parameters.update(
|
43
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
44
|
+
temperature: {default: @defaults[:temperature]},
|
45
|
+
template: {},
|
46
|
+
stream: {default: false}
|
47
|
+
)
|
48
|
+
chat_parameters.remap(response_format: :format)
|
40
49
|
end
|
41
50
|
|
42
51
|
# Returns the # of vector dimensions for the embeddings
|
@@ -150,33 +159,20 @@ module Langchain::LLM
|
|
150
159
|
|
151
160
|
# Generate a chat completion
|
152
161
|
#
|
153
|
-
# @param
|
154
|
-
# @
|
155
|
-
# @
|
156
|
-
# @
|
157
|
-
# @
|
158
|
-
# @
|
162
|
+
# @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
|
163
|
+
# @option params [String] :model Model name
|
164
|
+
# @option params [Array<Hash>] :messages Array of messages
|
165
|
+
# @option params [String] :format Format to return a response in. Currently the only accepted value is `json`
|
166
|
+
# @option params [Float] :temperature The temperature to use
|
167
|
+
# @option params [String] :template The prompt template to use (overrides what is defined in the `Modelfile`)
|
168
|
+
# @option params [Boolean] :stream Streaming the response. If false the response will be returned as a single response object, rather than a stream of objects
|
159
169
|
#
|
160
170
|
# The message object has the following fields:
|
161
171
|
# role: the role of the message, either system, user or assistant
|
162
172
|
# content: the content of the message
|
163
173
|
# images (optional): a list of images to include in the message (for multimodal models such as llava)
|
164
|
-
def chat(
|
165
|
-
|
166
|
-
messages: [],
|
167
|
-
format: nil,
|
168
|
-
temperature: defaults[:temperature],
|
169
|
-
template: nil,
|
170
|
-
stream: false # TODO: Fix streaming.
|
171
|
-
)
|
172
|
-
parameters = {
|
173
|
-
model: model,
|
174
|
-
messages: messages,
|
175
|
-
format: format,
|
176
|
-
temperature: temperature,
|
177
|
-
template: template,
|
178
|
-
stream: stream
|
179
|
-
}.compact
|
174
|
+
def chat(params = {})
|
175
|
+
parameters = chat_parameters.to_params(params)
|
180
176
|
|
181
177
|
response = client.post("api/chat") do |req|
|
182
178
|
req.body = parameters
|
data/lib/langchain/llm/openai.rb
CHANGED
@@ -40,6 +40,15 @@ module Langchain::LLM
|
|
40
40
|
@client = ::OpenAI::Client.new(access_token: api_key, **llm_options)
|
41
41
|
|
42
42
|
@defaults = DEFAULTS.merge(default_options)
|
43
|
+
chat_parameters.update(
|
44
|
+
model: {default: @defaults[:chat_completion_model_name]},
|
45
|
+
logprobs: {},
|
46
|
+
top_logprobs: {},
|
47
|
+
n: {default: @defaults[:n]},
|
48
|
+
temperature: {default: @defaults[:temperature]},
|
49
|
+
user: {}
|
50
|
+
)
|
51
|
+
chat_parameters.ignore(:top_k)
|
43
52
|
end
|
44
53
|
|
45
54
|
# Generate an embedding for a given text
|
@@ -102,54 +111,17 @@ module Langchain::LLM
|
|
102
111
|
|
103
112
|
# Generate a chat completion for given messages.
|
104
113
|
#
|
105
|
-
# @param
|
106
|
-
# @
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
presence_penalty: nil,
|
117
|
-
response_format: nil,
|
118
|
-
seed: nil,
|
119
|
-
stop: nil,
|
120
|
-
stream: nil,
|
121
|
-
temperature: defaults[:temperature],
|
122
|
-
top_p: nil,
|
123
|
-
tools: [],
|
124
|
-
tool_choice: nil,
|
125
|
-
user: nil,
|
126
|
-
&block
|
127
|
-
)
|
128
|
-
raise ArgumentError.new("messages argument is required") if messages.empty?
|
129
|
-
raise ArgumentError.new("model argument is required") if model.empty?
|
130
|
-
raise ArgumentError.new("'tool_choice' is only allowed when 'tools' are specified.") if tool_choice && tools.empty?
|
131
|
-
|
132
|
-
parameters = {
|
133
|
-
messages: messages,
|
134
|
-
model: model
|
135
|
-
}
|
136
|
-
parameters[:frequency_penalty] = frequency_penalty if frequency_penalty
|
137
|
-
parameters[:logit_bias] = logit_bias if logit_bias
|
138
|
-
parameters[:logprobs] = logprobs if logprobs
|
139
|
-
parameters[:top_logprobs] = top_logprobs if top_logprobs
|
140
|
-
# TODO: Fix max_tokens validation to account for tools/functions
|
141
|
-
parameters[:max_tokens] = max_tokens if max_tokens # || validate_max_tokens(parameters[:messages], parameters[:model])
|
142
|
-
parameters[:n] = n if n
|
143
|
-
parameters[:presence_penalty] = presence_penalty if presence_penalty
|
144
|
-
parameters[:response_format] = response_format if response_format
|
145
|
-
parameters[:seed] = seed if seed
|
146
|
-
parameters[:stop] = stop if stop
|
147
|
-
parameters[:stream] = stream if stream
|
148
|
-
parameters[:temperature] = temperature if temperature
|
149
|
-
parameters[:top_p] = top_p if top_p
|
150
|
-
parameters[:tools] = tools if tools.any?
|
151
|
-
parameters[:tool_choice] = tool_choice if tool_choice
|
152
|
-
parameters[:user] = user if user
|
114
|
+
# @param [Hash] params unified chat parmeters from [Langchain::LLM::Parameters::Chat::SCHEMA]
|
115
|
+
# @option params [Array<Hash>] :messages List of messages comprising the conversation so far
|
116
|
+
# @option params [String] :model ID of the model to use
|
117
|
+
def chat(params = {}, &block)
|
118
|
+
parameters = chat_parameters.to_params(params)
|
119
|
+
|
120
|
+
raise ArgumentError.new("messages argument is required") if Array(parameters[:messages]).empty?
|
121
|
+
raise ArgumentError.new("model argument is required") if parameters[:model].to_s.empty?
|
122
|
+
if parameters[:tool_choice] && Array(parameters[:tools]).empty?
|
123
|
+
raise ArgumentError.new("'tool_choice' is only allowed when 'tools' are specified.")
|
124
|
+
end
|
153
125
|
|
154
126
|
# TODO: Clean this part up
|
155
127
|
if block
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
5
|
+
module Langchain::LLM::Parameters
|
6
|
+
class Chat < SimpleDelegator
|
7
|
+
# TODO: At the moment, the UnifiedParamters only considers keys. In the
|
8
|
+
# future, we may consider ActiveModel-style validations and further typed
|
9
|
+
# options here.
|
10
|
+
SCHEMA = {
|
11
|
+
# Either "messages" or "prompt" is required
|
12
|
+
messages: {},
|
13
|
+
model: {},
|
14
|
+
prompt: {},
|
15
|
+
|
16
|
+
# System instructions. Used by Cohere, Anthropic and Google Gemini.
|
17
|
+
system: {},
|
18
|
+
|
19
|
+
# Allows to force the model to produce specific output format.
|
20
|
+
response_format: {},
|
21
|
+
|
22
|
+
stop: {}, # multiple types (e.g. OpenAI also allows Array, null)
|
23
|
+
stream: {}, # Enable streaming
|
24
|
+
|
25
|
+
max_tokens: {}, # Range: [1, context_length)
|
26
|
+
temperature: {}, # Range: [0, 2]
|
27
|
+
top_p: {}, # Range: (0, 1]
|
28
|
+
top_k: {}, # Range: [1, Infinity) Not available for OpenAI models
|
29
|
+
frequency_penalty: {}, # Range: [-2, 2]
|
30
|
+
presence_penalty: {}, # Range: [-2, 2]
|
31
|
+
repetition_penalty: {}, # Range: (0, 2]
|
32
|
+
seed: {}, # OpenAI only
|
33
|
+
|
34
|
+
# Function-calling
|
35
|
+
tools: {default: []},
|
36
|
+
tool_choice: {},
|
37
|
+
|
38
|
+
# Additional optional parameters
|
39
|
+
logit_bias: {}
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(parameters: {})
|
43
|
+
super(
|
44
|
+
::Langchain::LLM::UnifiedParameters.new(
|
45
|
+
schema: SCHEMA.dup,
|
46
|
+
parameters: parameters
|
47
|
+
)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -45,14 +45,14 @@ module Langchain
|
|
45
45
|
|
46
46
|
# Return the completion candidates
|
47
47
|
#
|
48
|
-
# @return [Array]
|
48
|
+
# @return [Array<String>]
|
49
49
|
def completions
|
50
50
|
raise NotImplementedError
|
51
51
|
end
|
52
52
|
|
53
53
|
# Return the chat completion candidates
|
54
54
|
#
|
55
|
-
# @return [Array]
|
55
|
+
# @return [Array<String>]
|
56
56
|
def chat_completions
|
57
57
|
raise NotImplementedError
|
58
58
|
end
|
@@ -17,5 +17,21 @@ module Langchain::LLM
|
|
17
17
|
def completion
|
18
18
|
completions&.dig(0, "text")
|
19
19
|
end
|
20
|
+
|
21
|
+
def chat_completion
|
22
|
+
raw_response.dig("text")
|
23
|
+
end
|
24
|
+
|
25
|
+
def role
|
26
|
+
raw_response.dig("chat_history").last["role"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def prompt_tokens
|
30
|
+
raw_response.dig("meta", "billed_units", "input_tokens")
|
31
|
+
end
|
32
|
+
|
33
|
+
def completion_tokens
|
34
|
+
raw_response.dig("meta", "billed_units", "output_tokens")
|
35
|
+
end
|
20
36
|
end
|
21
37
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Langchain::LLM
|
4
|
+
class UnifiedParameters
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :schema, :aliases, :parameters, :ignored, :remapped
|
8
|
+
|
9
|
+
class Null < self
|
10
|
+
def initialize(parameters: {})
|
11
|
+
super(schema: {}, parameters: parameters)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(schema:, parameters: {})
|
16
|
+
@schema = schema || {}
|
17
|
+
@aliases = {}
|
18
|
+
@remapped = {}
|
19
|
+
@ignored = Set.new
|
20
|
+
@schema.each do |name, param|
|
21
|
+
@aliases[name] = Set.new(Array(param[:aliases])) if param[:aliases]
|
22
|
+
end
|
23
|
+
@parameters = to_params(parameters.to_h) if !parameters.to_h.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_params(params = {})
|
27
|
+
# if params are provided, reset any previously initialized
|
28
|
+
@parameters = params if !params.empty?
|
29
|
+
@parameters = (@parameters || {}).merge!(params).slice(*schema.keys)
|
30
|
+
@aliases.each do |field, aliased_keys|
|
31
|
+
# favor existing keys in case of conflicts,
|
32
|
+
# and check for multiples
|
33
|
+
aliased_keys.each do |alias_key|
|
34
|
+
@parameters[field] ||= params[alias_key] if value_present?(params[alias_key])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@schema.each do |field, param_options|
|
38
|
+
param_options ||= {}
|
39
|
+
default = param_options[:default]
|
40
|
+
@parameters[field] ||= default if value_present?(default)
|
41
|
+
end
|
42
|
+
@remapped.each do |field, renamed_field|
|
43
|
+
@parameters[renamed_field] = @parameters[field] if value_present?(@parameters[field])
|
44
|
+
end
|
45
|
+
@parameters = @parameters.except(*@ignored + @remapped.keys)
|
46
|
+
end
|
47
|
+
|
48
|
+
def remap(field_map)
|
49
|
+
@remapped ||= {}
|
50
|
+
@remapped.merge!(field_map)
|
51
|
+
field_map.each do |field, renamed_field|
|
52
|
+
@schema[renamed_field] = @schema[field]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def update(schema = {})
|
57
|
+
@schema.merge!(schema)
|
58
|
+
schema.each do |name, param|
|
59
|
+
if param[:aliases]
|
60
|
+
@aliases[name] ||= Set.new
|
61
|
+
@aliases[name] << param[:aliases]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def ignore(*field_names)
|
68
|
+
@ignored.merge(field_names)
|
69
|
+
end
|
70
|
+
|
71
|
+
def alias_field(field_name, as:)
|
72
|
+
@aliases[field_name] ||= Set.new
|
73
|
+
@aliases[field_name] << as
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_h
|
77
|
+
@parameters.to_h
|
78
|
+
end
|
79
|
+
|
80
|
+
def each(&)
|
81
|
+
to_params.each(&)
|
82
|
+
end
|
83
|
+
|
84
|
+
def <=>(other)
|
85
|
+
to_params.<=>(other.to_params)
|
86
|
+
end
|
87
|
+
|
88
|
+
def [](key)
|
89
|
+
to_params[key]
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def value_present?(value)
|
95
|
+
!value.nil? && (!value.is_a?(Enumerable) || !value.empty?)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/langchain/loader.rb
CHANGED
@@ -29,9 +29,11 @@ module Langchain
|
|
29
29
|
# @param path [String | Pathname] path to file or URL
|
30
30
|
# @param options [Hash] options passed to the processor class used to process the data
|
31
31
|
# @return [Data] data loaded from path
|
32
|
+
# rubocop:disable Style/ArgumentsForwarding
|
32
33
|
def self.load(path, options = {}, &block)
|
33
34
|
new(path, options).load(&block)
|
34
35
|
end
|
36
|
+
# rubocop:enable Style/ArgumentsForwarding
|
35
37
|
|
36
38
|
# Initialize Langchain::Loader
|
37
39
|
# @param path [String | Pathname] path to file or URL
|
@@ -76,12 +78,14 @@ module Langchain
|
|
76
78
|
# @yieldreturn [String] parsed data, as a String
|
77
79
|
#
|
78
80
|
# @return [Data] data that was loaded
|
81
|
+
# rubocop:disable Style/ArgumentsForwarding
|
79
82
|
def load(&block)
|
80
83
|
return process_data(load_from_url, &block) if url?
|
81
84
|
return load_from_directory(&block) if directory?
|
82
85
|
|
83
86
|
process_data(load_from_path, &block)
|
84
87
|
end
|
88
|
+
# rubocop:enable Style/ArgumentsForwarding
|
85
89
|
|
86
90
|
private
|
87
91
|
|
@@ -95,6 +99,7 @@ module Langchain
|
|
95
99
|
raise FileNotFound, "File #{@path} does not exist"
|
96
100
|
end
|
97
101
|
|
102
|
+
# rubocop:disable Style/ArgumentsForwarding
|
98
103
|
def load_from_directory(&block)
|
99
104
|
Dir.glob(File.join(@path, "**/*")).map do |file|
|
100
105
|
# Only load and add to result files with supported extensions
|
@@ -103,6 +108,7 @@ module Langchain
|
|
103
108
|
UnknownFormatError nil
|
104
109
|
end.flatten.compact
|
105
110
|
end
|
111
|
+
# rubocop:enable Style/ArgumentsForwarding
|
106
112
|
|
107
113
|
def process_data(data, &block)
|
108
114
|
@raw_data = data
|
data/lib/langchain/tool/base.rb
CHANGED
@@ -3,13 +3,13 @@
|
|
3
3
|
module Langchain::Tool
|
4
4
|
# = Tools
|
5
5
|
#
|
6
|
-
# Tools are used by Agents to perform specific tasks.
|
6
|
+
# Tools are used by Agents to perform specific tasks. A 'Tool' is a collection of functions ("methods").
|
7
7
|
#
|
8
8
|
# == Available Tools
|
9
9
|
#
|
10
10
|
# - {Langchain::Tool::Calculator}: calculate the result of a math expression
|
11
11
|
# - {Langchain::Tool::Database}: executes SQL queries
|
12
|
-
# - {Langchain::Tool::FileSystem}: interacts with
|
12
|
+
# - {Langchain::Tool::FileSystem}: interacts with the file system
|
13
13
|
# - {Langchain::Tool::GoogleSearch}: search on Google (via SerpAPI)
|
14
14
|
# - {Langchain::Tool::RubyCodeInterpreter}: runs ruby code
|
15
15
|
# - {Langchain::Tool::Weather}: gets current weather data
|
@@ -42,10 +42,10 @@ module Langchain::Tool
|
|
42
42
|
#
|
43
43
|
# == Adding Tools
|
44
44
|
#
|
45
|
-
# 1. Create a new
|
46
|
-
# 2.
|
45
|
+
# 1. Create a new folder in lib/langchain/tool/your_tool_name/
|
46
|
+
# 2. Inside of this folder create a file with a class YourToolName that inherits from {Langchain::Tool::Base}
|
47
47
|
# 3. Add `NAME=` and `ANNOTATIONS_PATH=` constants in your Tool class
|
48
|
-
# 4. Implement various methods in your tool class
|
48
|
+
# 4. Implement various public methods in your tool class
|
49
49
|
# 5. Create a sidecar .json file in the same directory as your tool file annotating the methods in the Open API format
|
50
50
|
# 6. Add your tool to the {file:README.md}
|
51
51
|
class Base
|
@@ -28,10 +28,11 @@ module Langchain
|
|
28
28
|
"text-embedding-3-large" => 8191,
|
29
29
|
"text-embedding-3-small" => 8191,
|
30
30
|
"text-embedding-ada-002" => 8191,
|
31
|
-
"gpt-3.5-turbo" =>
|
31
|
+
"gpt-3.5-turbo" => 16385,
|
32
32
|
"gpt-3.5-turbo-0301" => 4096,
|
33
33
|
"gpt-3.5-turbo-0613" => 4096,
|
34
34
|
"gpt-3.5-turbo-1106" => 16385,
|
35
|
+
"gpt-3.5-turbo-0125" => 16385,
|
35
36
|
"gpt-3.5-turbo-16k" => 16384,
|
36
37
|
"gpt-3.5-turbo-16k-0613" => 16384,
|
37
38
|
"text-davinci-003" => 4097,
|
@@ -44,9 +45,13 @@ module Langchain
|
|
44
45
|
"gpt-4-32k-0314" => 32768,
|
45
46
|
"gpt-4-32k-0613" => 32768,
|
46
47
|
"gpt-4-1106-preview" => 128000,
|
48
|
+
"gpt-4-turbo" => 128000,
|
49
|
+
"gpt-4-turbo-2024-04-09" => 128000,
|
47
50
|
"gpt-4-turbo-preview" => 128000,
|
48
51
|
"gpt-4-0125-preview" => 128000,
|
49
52
|
"gpt-4-vision-preview" => 128000,
|
53
|
+
"gpt-4o" => 128000,
|
54
|
+
"gpt-4o-2024-05-13" => 128000,
|
50
55
|
"text-curie-001" => 2049,
|
51
56
|
"text-babbage-001" => 2049,
|
52
57
|
"text-ada-001" => 2049,
|
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.12.
|
4
|
+
version: 0.12.1
|
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-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -238,16 +238,16 @@ dependencies:
|
|
238
238
|
name: anthropic
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
240
240
|
requirements:
|
241
|
-
- - "
|
241
|
+
- - "~>"
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version: '0'
|
243
|
+
version: '0.2'
|
244
244
|
type: :development
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
|
-
- - "
|
248
|
+
- - "~>"
|
249
249
|
- !ruby/object:Gem::Version
|
250
|
-
version: '0'
|
250
|
+
version: '0.2'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: aws-sdk-bedrockruntime
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,14 +282,14 @@ dependencies:
|
|
282
282
|
requirements:
|
283
283
|
- - "~>"
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version: 0.9.
|
285
|
+
version: 0.9.10
|
286
286
|
type: :development
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
290
|
- - "~>"
|
291
291
|
- !ruby/object:Gem::Version
|
292
|
-
version: 0.9.
|
292
|
+
version: 0.9.10
|
293
293
|
- !ruby/object:Gem::Dependency
|
294
294
|
name: docx
|
295
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -742,6 +742,7 @@ files:
|
|
742
742
|
- lib/langchain/llm/mistral_ai.rb
|
743
743
|
- lib/langchain/llm/ollama.rb
|
744
744
|
- lib/langchain/llm/openai.rb
|
745
|
+
- lib/langchain/llm/parameters/chat.rb
|
745
746
|
- lib/langchain/llm/prompts/ollama/summarize_template.yaml
|
746
747
|
- lib/langchain/llm/prompts/summarize_template.yaml
|
747
748
|
- lib/langchain/llm/replicate.rb
|
@@ -758,6 +759,7 @@ files:
|
|
758
759
|
- lib/langchain/llm/response/ollama_response.rb
|
759
760
|
- lib/langchain/llm/response/openai_response.rb
|
760
761
|
- lib/langchain/llm/response/replicate_response.rb
|
762
|
+
- lib/langchain/llm/unified_parameters.rb
|
761
763
|
- lib/langchain/loader.rb
|
762
764
|
- lib/langchain/output_parsers/base.rb
|
763
765
|
- lib/langchain/output_parsers/output_fixing_parser.rb
|