langchainrb 0.15.4 → 0.15.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68d2d64fb264bf47488e83581540b88f7746f0e1b1b318d7dfc9c15356f40c8c
4
- data.tar.gz: efbd840632f0f22b202d9257a2020c4bc49cea7528d79efa7e05f963e9e4745f
3
+ metadata.gz: cb478a5261da82b78d6a90b6179e4050ae0fcba274c370b507f546b59cfd1a78
4
+ data.tar.gz: 7fb27d8b3c68060e923e69b1c67680be20846e5a384def4c6ce0efd1c9fa56ab
5
5
  SHA512:
6
- metadata.gz: f57817cc62de3af8f9aa80c62e421255e4172f55d54d91c1adc7d7a03ac9272e866670532c996a19d502c6d3110627d778efdad8c4faad0b07868c8b0aebc81c
7
- data.tar.gz: b35d82314edc0d747c87a37bd0e2036755f884e85977639e8b53063ca8ebd7002b9dd4ae9a5dd443f088552e575471e080dc9aa4519e25efaa908e16130b613a
6
+ metadata.gz: b6533a4064e822c78cc7659c55c948b13b4904d75ab99fb50269f82d7f815e02ff3c0659f0b6c1905b16c0834f2577ccd136cb3d1a34db6e26b7352c77350a10
7
+ data.tar.gz: 170e767e0fdef21fc6051a161904ee867205bb18a98641b545adf7fe3933b499d157be52009fd20e168efa5d94e5a03c39a1a21c94c2747b8e6a0393f2099e4e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.15.4] - 2024-09-10 🇧🇦
4
+ - Fix for Langchain::Prompt::PromptTemplate supporting nested JSON data
5
+ - Require common libs at top-level
6
+ - Add `add_message_callback` to `Langchain::Assistant` constructor to invoke an optional function when any message is added to the conversation
7
+ - Adding Assistant syntactic sugar with #run! and #add_message_and_run!
8
+
3
9
  ## [0.15.4] - 2024-08-30
4
10
  - Improve the Langchain::Tool::Database tool
5
11
  - Allow explictly setting tool_choice on the Assistant instance
data/README.md CHANGED
@@ -427,7 +427,7 @@ assistant.add_message_and_run(content: "What's the latest news about AI?")
427
427
  messages = assistant.messages
428
428
 
429
429
  # Run the assistant with automatic tool execution
430
- assistant.run(auto_tool_execution: true)
430
+ assistant.run!
431
431
  ```
432
432
 
433
433
  ### Configuration
@@ -435,11 +435,12 @@ assistant.run(auto_tool_execution: true)
435
435
  * `tools`: An array of tool instances (optional)
436
436
  * `instructions`: System instructions for the assistant (optional)
437
437
  * `tool_choice`: Specifies how tools should be selected. Default: "auto". A specific tool function name can be passed. This will force the Assistant to **always** use this function.
438
+ * `add_message_callback`: A callback function (proc, lambda) that is called when any message is added to the conversation (optional)
438
439
 
439
440
  ### Key Methods
440
441
  * `add_message`: Adds a user message to the messages array
441
- * `run`: Processes the conversation and generates responses
442
- * `add_message_and_run`: Combines adding a message and running the assistant
442
+ * `run!`: Processes the conversation and generates responses
443
+ * `add_message_and_run!`: Combines adding a message and running the assistant
443
444
  * `submit_tool_output`: Manually submit output to a tool call
444
445
  * `messages`: Returns a list of ongoing messages
445
446
 
@@ -30,7 +30,8 @@ module Langchain
30
30
  thread: nil,
31
31
  tools: [],
32
32
  instructions: nil,
33
- tool_choice: "auto"
33
+ tool_choice: "auto",
34
+ add_message_callback: nil
34
35
  )
35
36
  unless tools.is_a?(Array) && tools.all? { |tool| tool.class.singleton_class.included_modules.include?(Langchain::ToolDefinition) }
36
37
  raise ArgumentError, "Tools must be an array of objects extending Langchain::ToolDefinition"
@@ -38,7 +39,10 @@ module Langchain
38
39
 
39
40
  @llm = llm
40
41
  @llm_adapter = LLM::Adapter.build(llm)
42
+
41
43
  @thread = thread || Langchain::Thread.new
44
+ @thread.add_message_callback = add_message_callback
45
+
42
46
  @tools = tools
43
47
  self.tool_choice = tool_choice
44
48
  @instructions = instructions
@@ -51,9 +55,8 @@ module Langchain
51
55
  raise ArgumentError, "Thread must be an instance of Langchain::Thread" unless @thread.is_a?(Langchain::Thread)
52
56
 
53
57
  # The first message in the thread should be the system instructions
54
- # TODO: What if the user added old messages and the system instructions are already in there? Should this overwrite the existing instructions?
55
- initialize_instructions
56
58
  # For Google Gemini, and Anthropic system instructions are added to the `system:` param in the `chat` method
59
+ initialize_instructions
57
60
  end
58
61
 
59
62
  # Add a user message to the thread
@@ -107,6 +110,13 @@ module Langchain
107
110
  thread.messages
108
111
  end
109
112
 
113
+ # Run the assistant with automatic tool execution
114
+ #
115
+ # @return [Array<Langchain::Message>] The messages in the thread
116
+ def run!
117
+ run(auto_tool_execution: true)
118
+ end
119
+
110
120
  # Add a user message to the thread and run the assistant
111
121
  #
112
122
  # @param content [String] The content of the message
@@ -117,6 +127,14 @@ module Langchain
117
127
  run(auto_tool_execution: auto_tool_execution)
118
128
  end
119
129
 
130
+ # Add a user message to the thread and run the assistant with automatic tool execution
131
+ #
132
+ # @param content [String] The content of the message
133
+ # @return [Array<Langchain::Message>] The messages in the thread
134
+ def add_message_and_run!(content:)
135
+ add_message_and_run(content: content, auto_tool_execution: true)
136
+ end
137
+
120
138
  # Submit tool output to the thread
121
139
  #
122
140
  # @param tool_call_id [String] The ID of the tool call to submit output for
@@ -287,7 +305,7 @@ module Langchain
287
305
 
288
306
  def initialize_instructions
289
307
  if llm.is_a?(Langchain::LLM::OpenAI) || llm.is_a?(Langchain::LLM::MistralAI)
290
- add_message(role: "system", content: instructions) if instructions
308
+ self.instructions = @instructions if @instructions
291
309
  end
292
310
  end
293
311
 
@@ -4,12 +4,14 @@ module Langchain
4
4
  # Langchain::Thread keeps track of messages in a conversation.
5
5
  # TODO: Add functionality to persist to the thread to disk, DB, storage, etc.
6
6
  class Thread
7
- attr_accessor :messages
7
+ attr_accessor :messages, :add_message_callback
8
8
 
9
9
  # @param messages [Array<Langchain::Message>]
10
- def initialize(messages: [])
10
+ # @param add_message_callback [Proc] A callback to call when a message is added to the thread
11
+ def initialize(messages: [], add_message_callback: nil)
11
12
  raise ArgumentError, "messages array must only contain Langchain::Message instance(s)" unless messages.is_a?(Array) && messages.all? { |m| m.is_a?(Langchain::Messages::Base) }
12
13
 
14
+ @add_message_callback = add_message_callback
13
15
  @messages = messages
14
16
  end
15
17
 
@@ -34,6 +36,9 @@ module Langchain
34
36
  def add_message(message)
35
37
  raise ArgumentError, "message must be a Langchain::Message instance" unless message.is_a?(Langchain::Messages::Base)
36
38
 
39
+ # Call the callback with the message
40
+ add_message_callback.call(message) if add_message_callback # rubocop:disable Style/SafeNavigation
41
+
37
42
  # Prepend the message to the thread
38
43
  messages << message
39
44
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
3
  require "json-schema"
5
4
 
6
5
  module Langchain::OutputParsers
@@ -1,4 +1,4 @@
1
- require "uri"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
4
  module Processors
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "strscan"
4
- require "json"
5
4
  require "yaml"
6
5
 
7
6
  module Langchain::Prompt
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "strscan"
4
4
  require "pathname"
5
- require "json"
6
5
  require "yaml"
7
6
 
8
7
  module Langchain::Prompt
@@ -58,8 +58,9 @@ module Langchain::Prompt
58
58
  #
59
59
  def format(**kwargs)
60
60
  result = @template
61
+ result = result.gsub(/{{/, "{").gsub(/}}/, "}")
61
62
  kwargs.each { |key, value| result = result.gsub(/\{#{key}\}/, value.to_s) }
62
- result.gsub(/{{/, "{").gsub(/}}/, "}")
63
+ result
63
64
  end
64
65
 
65
66
  #
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  #
6
4
  # Extends a class to be used as a tool in the assistant.
7
5
  # A tool is a collection of functions (methods) used to perform specific tasks.
@@ -42,8 +40,8 @@ module Langchain::ToolDefinition
42
40
  # @param method_name [Symbol] Name of the method to define
43
41
  # @param description [String] Description of the function
44
42
  # @yield Block that defines the parameters for the function
45
- def define_function(method_name, description:, &)
46
- function_schemas.add_function(method_name:, description:, &)
43
+ def define_function(method_name, description:, &block)
44
+ function_schemas.add_function(method_name:, description:, &block)
47
45
  end
48
46
 
49
47
  # Returns the FunctionSchemas instance for this tool
@@ -76,11 +74,11 @@ module Langchain::ToolDefinition
76
74
  # @param description [String] Description of the function
77
75
  # @yield Block that defines the parameters for the function
78
76
  # @raise [ArgumentError] If a block is defined and no parameters are specified for the function
79
- def add_function(method_name:, description:, &)
77
+ def add_function(method_name:, description:, &block)
80
78
  name = "#{@tool_name}__#{method_name}"
81
79
 
82
- if block_given?
83
- parameters = ParameterBuilder.new(parent_type: "object").build(&)
80
+ if block_given? # rubocop:disable Performance/BlockGivenWithExplicitBlock
81
+ parameters = ParameterBuilder.new(parent_type: "object").build(&block)
84
82
 
85
83
  if parameters[:properties].empty?
86
84
  raise ArgumentError, "Function parameters must have at least one property defined within it, if a block is provided"
@@ -130,8 +128,8 @@ module Langchain::ToolDefinition
130
128
  #
131
129
  # @yield Block that defines the properties of the schema
132
130
  # @return [Hash] The built schema
133
- def build(&)
134
- instance_eval(&)
131
+ def build(&block)
132
+ instance_eval(&block)
135
133
  @schema
136
134
  end
137
135
 
@@ -144,13 +142,13 @@ module Langchain::ToolDefinition
144
142
  # @param required [Boolean] Whether the property is required
145
143
  # @yield [Block] Block for nested properties (only for object and array types)
146
144
  # @raise [ArgumentError] If any parameter is invalid
147
- def property(name = nil, type:, description: nil, enum: nil, required: false, &)
145
+ def property(name = nil, type:, description: nil, enum: nil, required: false, &block)
148
146
  validate_parameters(name:, type:, enum:, required:)
149
147
 
150
148
  prop = {type:, description:, enum:}.compact
151
149
 
152
- if block_given?
153
- nested_schema = ParameterBuilder.new(parent_type: type).build(&)
150
+ if block_given? # rubocop:disable Performance/BlockGivenWithExplicitBlock
151
+ nested_schema = ParameterBuilder.new(parent_type: type).build(&block)
154
152
 
155
153
  case type
156
154
  when "object"
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "securerandom"
4
- require "json"
5
4
  require "timeout"
6
- require "uri"
7
5
 
8
6
  module Langchain::Vectorsearch
9
7
  class Epsilla < Base
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
- VERSION = "0.15.4"
4
+ VERSION = "0.15.5"
5
5
  end
data/lib/langchain.rb CHANGED
@@ -4,6 +4,9 @@ require "logger"
4
4
  require "pathname"
5
5
  require "rainbow"
6
6
  require "zeitwerk"
7
+ require "uri"
8
+ require "json"
9
+
7
10
  loader = Zeitwerk::Loader.for_gem
8
11
  loader.ignore("#{__dir__}/langchainrb.rb")
9
12
  loader.inflector.inflect(
@@ -30,6 +33,7 @@ loader.collapse("#{__dir__}/langchain/assistants")
30
33
 
31
34
  loader.collapse("#{__dir__}/langchain/tool/calculator")
32
35
  loader.collapse("#{__dir__}/langchain/tool/database")
36
+ loader.collapse("#{__dir__}/langchain/tool/docs_tool")
33
37
  loader.collapse("#{__dir__}/langchain/tool/file_system")
34
38
  loader.collapse("#{__dir__}/langchain/tool/google_search")
35
39
  loader.collapse("#{__dir__}/langchain/tool/ruby_code_interpreter")
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.15.4
4
+ version: 0.15.5
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-08-30 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: baran