langchainrb 0.9.2 → 0.9.4

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +12 -19
  4. data/lib/langchain/agent/react_agent.rb +2 -0
  5. data/lib/langchain/agent/sql_query_agent.rb +2 -0
  6. data/lib/langchain/assistants/assistant.rb +8 -24
  7. data/lib/langchain/assistants/thread.rb +2 -2
  8. data/lib/langchain/chunker/markdown.rb +0 -2
  9. data/lib/langchain/chunker/recursive_text.rb +0 -2
  10. data/lib/langchain/chunker/semantic.rb +1 -3
  11. data/lib/langchain/chunker/sentence.rb +0 -2
  12. data/lib/langchain/chunker/text.rb +0 -2
  13. data/lib/langchain/contextual_logger.rb +1 -1
  14. data/lib/langchain/conversation/memory.rb +2 -0
  15. data/lib/langchain/conversation/message.rb +2 -0
  16. data/lib/langchain/llm/ollama.rb +40 -3
  17. data/lib/langchain/llm/openai.rb +16 -4
  18. data/lib/langchain/llm/prompts/ollama/summarize_template.yaml +9 -0
  19. data/lib/langchain/output_parsers/base.rb +0 -4
  20. data/lib/langchain/output_parsers/output_fixing_parser.rb +6 -13
  21. data/lib/langchain/output_parsers/structured_output_parser.rb +0 -10
  22. data/lib/langchain/processors/eml.rb +65 -0
  23. data/lib/langchain/tool/base.rb +17 -32
  24. data/lib/langchain/tool/calculator/calculator.json +19 -0
  25. data/lib/langchain/tool/{calculator.rb → calculator/calculator.rb} +8 -5
  26. data/lib/langchain/tool/database/database.json +46 -0
  27. data/lib/langchain/tool/database/database.rb +105 -0
  28. data/lib/langchain/tool/google_search/google_search.json +19 -0
  29. data/lib/langchain/tool/{google_search.rb → google_search/google_search.rb} +5 -6
  30. data/lib/langchain/tool/ruby_code_interpreter/ruby_code_interpreter.json +19 -0
  31. data/lib/langchain/tool/{ruby_code_interpreter.rb → ruby_code_interpreter/ruby_code_interpreter.rb} +9 -1
  32. data/lib/langchain/tool/weather/weather.json +19 -0
  33. data/lib/langchain/tool/{weather.rb → weather/weather.rb} +3 -4
  34. data/lib/langchain/tool/wikipedia/wikipedia.json +19 -0
  35. data/lib/langchain/tool/{wikipedia.rb → wikipedia/wikipedia.rb} +10 -1
  36. data/lib/langchain/vectorsearch/base.rb +1 -1
  37. data/lib/langchain/version.rb +1 -1
  38. data/lib/langchain.rb +8 -1
  39. metadata +80 -16
  40. data/lib/langchain/tool/database.rb +0 -90
@@ -0,0 +1,65 @@
1
+ require "mail"
2
+ require "uri"
3
+
4
+ module Langchain
5
+ module Processors
6
+ class Eml < Base
7
+ EXTENSIONS = [".eml"]
8
+ CONTENT_TYPES = ["message/rfc822"]
9
+
10
+ def initialize(*)
11
+ depends_on "mail"
12
+ end
13
+
14
+ # Parse the document and return the cleaned text
15
+ # @param [File] data
16
+ # @return [String]
17
+ def parse(data)
18
+ mail = Mail.read(data.path)
19
+ text_content = extract_text_content(mail)
20
+ clean_content(text_content)
21
+ end
22
+
23
+ private
24
+
25
+ # Extract text content from the email, preferring plaintext over HTML
26
+ def extract_text_content(mail)
27
+ text_content = ""
28
+ text_content += "From: #{mail.from}\n" \
29
+ "To: #{mail.to}\n" \
30
+ "Cc: #{mail.cc}\n" \
31
+ "Bcc: #{mail.bcc}\n" \
32
+ "Subject: #{mail.subject}\n" \
33
+ "Date: #{mail.date}\n\n"
34
+ if mail.multipart?
35
+ mail.parts.each do |part|
36
+ if part.content_type.start_with?("text/plain")
37
+ text_content += part.body.decoded.force_encoding("UTF-8").strip + "\n"
38
+ elsif part.content_type.start_with?("multipart/alternative", "multipart/mixed")
39
+ text_content += extract_text_content(part) + "\n" # Recursively extract from multipart
40
+ elsif part.content_type.start_with?("message/rfc822")
41
+ # Handle embedded .eml parts as separate emails
42
+ embedded_mail = Mail.read_from_string(part.body.decoded)
43
+ text_content += "--- Begin Embedded Email ---\n"
44
+ text_content += extract_text_content(embedded_mail) + "\n"
45
+ text_content += "--- End Embedded Email ---\n"
46
+ end
47
+ end
48
+ elsif mail.content_type.start_with?("text/plain")
49
+ text_content = mail.body.decoded.force_encoding("UTF-8").strip
50
+ end
51
+ text_content
52
+ end
53
+
54
+ # Clean and format the extracted content
55
+ def clean_content(content)
56
+ content
57
+ .gsub(/\[cid:[^\]]+\]/, "") # Remove embedded image references
58
+ .gsub(URI::DEFAULT_PARSER.make_regexp(%w[http https])) { |match| "<#{match}>" } # Format URLs
59
+ .gsub(/\r\n?/, "\n") # Normalize line endings to Unix style
60
+ .gsub(/[\u200B-\u200D\uFEFF]/, "") # Remove zero width spaces and similar characters
61
+ .gsub(/<\/?[^>]+>/, "") # Remove any HTML tags that might have sneaked in
62
+ end
63
+ end
64
+ end
65
+ end
@@ -48,11 +48,9 @@ module Langchain::Tool
48
48
  class Base
49
49
  include Langchain::DependencyHelper
50
50
 
51
- #
52
51
  # Returns the NAME constant of the tool
53
52
  #
54
53
  # @return [String] tool name
55
- #
56
54
  def name
57
55
  self.class.const_get(:NAME)
58
56
  end
@@ -63,59 +61,37 @@ module Langchain::Tool
63
61
  }
64
62
  end
65
63
 
66
- #
67
64
  # Returns the DESCRIPTION constant of the tool
68
65
  #
69
66
  # @return [String] tool description
70
- #
71
67
  def description
72
68
  self.class.const_get(:DESCRIPTION)
73
69
  end
74
70
 
75
- #
76
71
  # Sets the DESCRIPTION constant of the tool
77
72
  #
78
73
  # @param value [String] tool description
79
- #
80
74
  def self.description(value)
81
75
  const_set(:DESCRIPTION, value.tr("\n", " ").strip)
82
76
  end
83
77
 
84
- #
85
78
  # Instantiates and executes the tool and returns the answer
86
79
  #
87
80
  # @param input [String] input to the tool
88
81
  # @return [String] answer
89
- #
90
82
  def self.execute(input:)
83
+ warn "DEPRECATED: `#{self}.execute` is deprecated, and will be removed in the next major version."
84
+
91
85
  new.execute(input: input)
92
86
  end
93
87
 
94
- # Returns the tool as an OpenAI tool
88
+ # Returns the tool as a list of OpenAI formatted functions
95
89
  #
96
90
  # @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
- }
91
+ def to_openai_tools
92
+ method_annotations
116
93
  end
117
94
 
118
- #
119
95
  # Executes the tool and returns the answer
120
96
  #
121
97
  # @param input [String] input to the tool
@@ -125,12 +101,21 @@ module Langchain::Tool
125
101
  raise NotImplementedError, "Your tool must implement the `#execute(input:)` method that returns a string"
126
102
  end
127
103
 
128
- #
104
+ # Return tool's method annotations as JSON
105
+ #
106
+ # @return [Hash] Tool's method annotations
107
+ def method_annotations
108
+ JSON.parse(
109
+ File.read(
110
+ self.class.const_get(:ANNOTATIONS_PATH)
111
+ )
112
+ )
113
+ end
114
+
129
115
  # Validates the list of tools or raises an error
130
- # @param tools [Array<Langchain::Tool>] list of tools to be used
131
116
  #
117
+ # @param tools [Array<Langchain::Tool>] list of tools to be used
132
118
  # @raise [ArgumentError] If any of the tools are not supported
133
- #
134
119
  def self.validate_tools!(tools:)
135
120
  # Check if the tool count is equal to unique tool count
136
121
  if tools.count != tools.map(&:name).uniq.count
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "calculator-execute",
6
+ "description": "Evaluates a pure math expression or if equation contains non-math characters (e.g.: \"12F in Celsius\") then it uses the google search calculator to evaluate the expression",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "input": {
11
+ "type": "string",
12
+ "description": "math expression"
13
+ }
14
+ },
15
+ "required": ["input"]
16
+ }
17
+ }
18
+ }
19
+ ]
@@ -6,11 +6,14 @@ module Langchain::Tool
6
6
  # A calculator tool that falls back to the Google calculator widget
7
7
  #
8
8
  # Gem requirements:
9
- # gem "eqn", "~> 1.6.5"
10
- # gem "google_search_results", "~> 2.0.0"
9
+ # gem "eqn", "~> 1.6.5"
10
+ # gem "google_search_results", "~> 2.0.0"
11
+ #
12
+ # Usage:
13
+ # calculator = Langchain::Tool::Calculator.new
11
14
  #
12
-
13
15
  NAME = "calculator"
16
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
14
17
 
15
18
  description <<~DESC
16
19
  Useful for getting the result of a math expression.
@@ -27,8 +30,8 @@ module Langchain::Tool
27
30
  depends_on "eqn"
28
31
  end
29
32
 
30
- # Evaluates a pure math expression or if equation contains non-math characters (e.g.: "12F in Celsius") then
31
- # it uses the google search calculator to evaluate the expression
33
+ # Evaluates a pure math expression or if equation contains non-math characters (e.g.: "12F in Celsius") then it uses the google search calculator to evaluate the expression
34
+ #
32
35
  # @param input [String] math expression
33
36
  # @return [String] Answer
34
37
  def execute(input:)
@@ -0,0 +1,46 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "database-describe_tables",
6
+ "description": "Database Tool: Returns the schema for a list of tables",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "tables": {
11
+ "type": "string",
12
+ "description": "The tables to describe."
13
+ }
14
+ },
15
+ "required": ["tables"]
16
+ }
17
+ }
18
+ }, {
19
+ "type": "function",
20
+ "function": {
21
+ "name": "database-list_tables",
22
+ "description": "Database Tool: Returns a list of tables in the database",
23
+ "parameters": {
24
+ "type": "object",
25
+ "properties": {},
26
+ "required": []
27
+ }
28
+ }
29
+ }, {
30
+ "type": "function",
31
+ "function": {
32
+ "name": "database-execute",
33
+ "description": "Database Tool: Executes a SQL query and returns the results",
34
+ "parameters": {
35
+ "type": "object",
36
+ "properties": {
37
+ "input": {
38
+ "type": "string",
39
+ "description": "SQL query to be executed"
40
+ }
41
+ },
42
+ "required": ["input"]
43
+ }
44
+ }
45
+ }
46
+ ]
@@ -0,0 +1,105 @@
1
+ module Langchain::Tool
2
+ class Database < Base
3
+ #
4
+ # Connects to a database, executes SQL queries, and outputs DB schema for Agents to use
5
+ #
6
+ # Gem requirements:
7
+ # gem "sequel", "~> 5.68.0"
8
+ #
9
+ # Usage:
10
+ # database = Langchain::Tool::Database.new(connection_string: "postgres://user:password@localhost:5432/db_name")
11
+ #
12
+ NAME = "database"
13
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
14
+
15
+ description <<~DESC
16
+ Useful for getting the result of a database query.
17
+
18
+ The input to this tool should be valid SQL.
19
+ DESC
20
+
21
+ attr_reader :db, :requested_tables, :excluded_tables
22
+
23
+ # Establish a database connection
24
+ #
25
+ # @param connection_string [String] Database connection info, e.g. 'postgres://user:password@localhost:5432/db_name'
26
+ # @param tables [Array<Symbol>] The tables to use. Will use all if empty.
27
+ # @param except_tables [Array<Symbol>] The tables to exclude. Will exclude none if empty.
28
+ # @return [Database] Database object
29
+ def initialize(connection_string:, tables: [], exclude_tables: [])
30
+ depends_on "sequel"
31
+
32
+ raise StandardError, "connection_string parameter cannot be blank" if connection_string.empty?
33
+
34
+ @db = Sequel.connect(connection_string)
35
+ @requested_tables = tables
36
+ @excluded_tables = exclude_tables
37
+ end
38
+
39
+ # Database Tool: Returns a list of tables in the database
40
+ def list_tables
41
+ db.tables
42
+ end
43
+
44
+ # Database Tool: Returns the schema for a list of tables
45
+ #
46
+ # @param tables [String] The tables to describe.
47
+ # @return [String] Database schema for the tables
48
+ def describe_tables(tables:)
49
+ schema = ""
50
+ tables.split(",").each do |table|
51
+ describe_table(table, schema)
52
+ end
53
+ schema
54
+ end
55
+
56
+ # Database Tool: Returns the database schema
57
+ #
58
+ # @return [String] Database schema
59
+ def dump_schema
60
+ Langchain.logger.info("Dumping schema tables and keys", for: self.class)
61
+ schema = ""
62
+ db.tables.each do |table|
63
+ describe_table(table, schema)
64
+ end
65
+ schema
66
+ end
67
+
68
+ def describe_table(table, schema)
69
+ primary_key_columns = []
70
+ primary_key_column_count = db.schema(table).count { |column| column[1][:primary_key] == true }
71
+
72
+ schema << "CREATE TABLE #{table}(\n"
73
+ db.schema(table).each do |column|
74
+ schema << "#{column[0]} #{column[1][:type]}"
75
+ if column[1][:primary_key] == true
76
+ schema << " PRIMARY KEY" if primary_key_column_count == 1
77
+ else
78
+ primary_key_columns << column[0]
79
+ end
80
+ schema << ",\n" unless column == db.schema(table).last && primary_key_column_count == 1
81
+ end
82
+ if primary_key_column_count > 1
83
+ schema << "PRIMARY KEY (#{primary_key_columns.join(",")})"
84
+ end
85
+ db.foreign_key_list(table).each do |fk|
86
+ schema << ",\n" if fk == db.foreign_key_list(table).first
87
+ schema << "FOREIGN KEY (#{fk[:columns][0]}) REFERENCES #{fk[:table]}(#{fk[:key][0]})"
88
+ schema << ",\n" unless fk == db.foreign_key_list(table).last
89
+ end
90
+ schema << ");\n"
91
+ end
92
+
93
+ # Database Tool: Executes a SQL query and returns the results
94
+ #
95
+ # @param input [String] SQL query to be executed
96
+ # @return [Array] Results from the SQL query
97
+ def execute(input:)
98
+ Langchain.logger.info("Executing \"#{input}\"", for: self.class)
99
+
100
+ db[input].to_a
101
+ rescue Sequel::DatabaseError => e
102
+ Langchain.logger.error(e.message, for: self.class)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "google_search-execute",
6
+ "description": "Executes Google Search and returns the result",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "input": {
11
+ "type": "string",
12
+ "description": "search query"
13
+ }
14
+ },
15
+ "required": ["input"]
16
+ }
17
+ }
18
+ }
19
+ ]
@@ -5,14 +5,15 @@ module Langchain::Tool
5
5
  #
6
6
  # Wrapper around SerpApi's Google Search API
7
7
  #
8
- # Gem requirements: gem "google_search_results", "~> 2.0.0"
8
+ # Gem requirements:
9
+ # gem "google_search_results", "~> 2.0.0"
9
10
  #
10
11
  # Usage:
11
- # search = Langchain::Tool::GoogleSearch.new(api_key: "YOUR_API_KEY")
12
- # search.execute(input: "What is the capital of France?")
12
+ # search = Langchain::Tool::GoogleSearch.new(api_key: "YOUR_API_KEY")
13
+ # search.execute(input: "What is the capital of France?")
13
14
  #
14
-
15
15
  NAME = "google_search"
16
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
16
17
 
17
18
  description <<~DESC
18
19
  A wrapper around SerpApi's Google Search API.
@@ -44,12 +45,10 @@ module Langchain::Tool
44
45
  new.execute_search(input: input)
45
46
  end
46
47
 
47
- #
48
48
  # Executes Google Search and returns the result
49
49
  #
50
50
  # @param input [String] search query
51
51
  # @return [String] Answer
52
- #
53
52
  def execute(input:)
54
53
  Langchain.logger.info("Executing \"#{input}\"", for: self.class)
55
54
 
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "ruby_code_interpreter-execute",
6
+ "description": "Executes Ruby code in a sandboxes environment.",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "input": {
11
+ "type": "string",
12
+ "description": "ruby code expression"
13
+ }
14
+ },
15
+ "required": ["input"]
16
+ }
17
+ }
18
+ }
19
+ ]
@@ -5,9 +5,15 @@ module Langchain::Tool
5
5
  #
6
6
  # A tool that execute Ruby code in a sandboxed environment.
7
7
  #
8
- # Gem requirements: gem "safe_ruby", "~> 1.0.4"
8
+ # Gem requirements:
9
+ # gem "safe_ruby", "~> 1.0.4"
10
+ #
11
+ # Usage:
12
+ # interpreter = Langchain::Tool::RubyCodeInterpreter.new
9
13
  #
10
14
  NAME = "ruby_code_interpreter"
15
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
16
+
11
17
  description <<~DESC
12
18
  A Ruby code interpreter. Use this to execute ruby expressions. Input should be a valid ruby expression. If you want to see the output of the tool, make sure to return a value.
13
19
  DESC
@@ -18,6 +24,8 @@ module Langchain::Tool
18
24
  @timeout = timeout
19
25
  end
20
26
 
27
+ # Executes Ruby code in a sandboxes environment.
28
+ #
21
29
  # @param input [String] ruby code expression
22
30
  # @return [String] Answer
23
31
  def execute(input:)
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "weather-execute",
6
+ "description": "Returns current weather for a city",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "input": {
11
+ "type": "string",
12
+ "description": "comma separated city and unit (optional: imperial, metric, or standard)"
13
+ }
14
+ },
15
+ "required": ["input"]
16
+ }
17
+ }
18
+ }
19
+ ]
@@ -13,11 +13,11 @@ module Langchain::Tool
13
13
  # api_key: https://home.openweathermap.org/api_keys
14
14
  #
15
15
  # Usage:
16
- # weather = Langchain::Tool::Weather.new(api_key: "YOUR_API_KEY")
16
+ # weather = Langchain::Tool::Weather.new(api_key: ENV["OPEN_WEATHER_API_KEY"])
17
17
  # weather.execute(input: "Boston, MA; imperial")
18
18
  #
19
-
20
19
  NAME = "weather"
20
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
21
21
 
22
22
  description <<~DESC
23
23
  Useful for getting current weather data
@@ -32,12 +32,10 @@ module Langchain::Tool
32
32
 
33
33
  attr_reader :client, :units
34
34
 
35
- #
36
35
  # Initializes the Weather tool
37
36
  #
38
37
  # @param api_key [String] Open Weather API key
39
38
  # @return [Langchain::Tool::Weather] Weather tool
40
- #
41
39
  def initialize(api_key:, units: "metric")
42
40
  depends_on "open-weather-ruby-client"
43
41
  require "open-weather-ruby-client"
@@ -51,6 +49,7 @@ module Langchain::Tool
51
49
  end
52
50
 
53
51
  # Returns current weather for a city
52
+ #
54
53
  # @param input [String] comma separated city and unit (optional: imperial, metric, or standard)
55
54
  # @return [String] Answer
56
55
  def execute(input:)
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "wikipedia-execute",
6
+ "description": "Executes Wikipedia API search and returns the answer",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "input": {
11
+ "type": "string",
12
+ "description": "search query"
13
+ }
14
+ },
15
+ "required": ["input"]
16
+ }
17
+ }
18
+ }
19
+ ]
@@ -5,9 +5,16 @@ module Langchain::Tool
5
5
  #
6
6
  # Tool that adds the capability to search using the Wikipedia API
7
7
  #
8
- # Gem requirements: gem "wikipedia-client", "~> 1.17.0"
8
+ # Gem requirements:
9
+ # gem "wikipedia-client", "~> 1.17.0"
10
+ #
11
+ # Usage:
12
+ # weather = Langchain::Tool::Wikipedia.new
13
+ # weather.execute(input: "The Roman Empire")
9
14
  #
10
15
  NAME = "wikipedia"
16
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
17
+
11
18
  description <<~DESC
12
19
  A wrapper around Wikipedia.
13
20
 
@@ -17,11 +24,13 @@ module Langchain::Tool
17
24
  Input should be a search query.
18
25
  DESC
19
26
 
27
+ # Initializes the Wikipedia tool
20
28
  def initialize
21
29
  depends_on "wikipedia-client", req: "wikipedia"
22
30
  end
23
31
 
24
32
  # Executes Wikipedia API search and returns the answer
33
+ #
25
34
  # @param input [String] search query
26
35
  # @return [String] Answer
27
36
  def execute(input:)
@@ -136,7 +136,7 @@ module Langchain::Vectorsearch
136
136
  # @param k [Integer] The number of results to return
137
137
  # @return [String] Response
138
138
  def similarity_search_with_hyde(query:, k: 4)
139
- hyde_completion = llm.complete(prompt: generate_hyde_prompt(question: query))
139
+ hyde_completion = llm.complete(prompt: generate_hyde_prompt(question: query)).completion
140
140
  similarity_search(query: hyde_completion, k: k)
141
141
  end
142
142
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
- VERSION = "0.9.2"
4
+ VERSION = "0.9.4"
5
5
  end
data/lib/langchain.rb CHANGED
@@ -25,6 +25,13 @@ loader.inflector.inflect(
25
25
  )
26
26
  loader.collapse("#{__dir__}/langchain/llm/response")
27
27
  loader.collapse("#{__dir__}/langchain/assistants")
28
+
29
+ loader.collapse("#{__dir__}/langchain/tool/calculator")
30
+ loader.collapse("#{__dir__}/langchain/tool/database")
31
+ loader.collapse("#{__dir__}/langchain/tool/google_search")
32
+ loader.collapse("#{__dir__}/langchain/tool/ruby_code_interpreter")
33
+ loader.collapse("#{__dir__}/langchain/tool/weather")
34
+ loader.collapse("#{__dir__}/langchain/tool/wikipedia")
28
35
  loader.setup
29
36
 
30
37
  # 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.
@@ -65,7 +72,7 @@ loader.setup
65
72
  #
66
73
  # = Logging
67
74
  #
68
- # LangChain.rb uses standard logging mechanisms and defaults to :debug level. Most messages are at info level, but we will add debug or warn statements as needed. To show all log messages:
75
+ # Langchain.rb uses standard logging mechanisms and defaults to :debug level. Most messages are at info level, but we will add debug or warn statements as needed. To show all log messages:
69
76
  #
70
77
  # Langchain.logger.level = :info
71
78
  module Langchain