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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +12 -19
- data/lib/langchain/agent/react_agent.rb +2 -0
- data/lib/langchain/agent/sql_query_agent.rb +2 -0
- data/lib/langchain/assistants/assistant.rb +8 -24
- data/lib/langchain/assistants/thread.rb +2 -2
- data/lib/langchain/chunker/markdown.rb +0 -2
- data/lib/langchain/chunker/recursive_text.rb +0 -2
- data/lib/langchain/chunker/semantic.rb +1 -3
- data/lib/langchain/chunker/sentence.rb +0 -2
- data/lib/langchain/chunker/text.rb +0 -2
- data/lib/langchain/contextual_logger.rb +1 -1
- data/lib/langchain/conversation/memory.rb +2 -0
- data/lib/langchain/conversation/message.rb +2 -0
- data/lib/langchain/llm/ollama.rb +40 -3
- data/lib/langchain/llm/openai.rb +16 -4
- data/lib/langchain/llm/prompts/ollama/summarize_template.yaml +9 -0
- data/lib/langchain/output_parsers/base.rb +0 -4
- data/lib/langchain/output_parsers/output_fixing_parser.rb +6 -13
- data/lib/langchain/output_parsers/structured_output_parser.rb +0 -10
- data/lib/langchain/processors/eml.rb +65 -0
- data/lib/langchain/tool/base.rb +17 -32
- data/lib/langchain/tool/calculator/calculator.json +19 -0
- data/lib/langchain/tool/{calculator.rb → calculator/calculator.rb} +8 -5
- data/lib/langchain/tool/database/database.json +46 -0
- data/lib/langchain/tool/database/database.rb +105 -0
- data/lib/langchain/tool/google_search/google_search.json +19 -0
- data/lib/langchain/tool/{google_search.rb → google_search/google_search.rb} +5 -6
- data/lib/langchain/tool/ruby_code_interpreter/ruby_code_interpreter.json +19 -0
- data/lib/langchain/tool/{ruby_code_interpreter.rb → ruby_code_interpreter/ruby_code_interpreter.rb} +9 -1
- data/lib/langchain/tool/weather/weather.json +19 -0
- data/lib/langchain/tool/{weather.rb → weather/weather.rb} +3 -4
- data/lib/langchain/tool/wikipedia/wikipedia.json +19 -0
- data/lib/langchain/tool/{wikipedia.rb → wikipedia/wikipedia.rb} +10 -1
- data/lib/langchain/vectorsearch/base.rb +1 -1
- data/lib/langchain/version.rb +1 -1
- data/lib/langchain.rb +8 -1
- metadata +80 -16
- 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
|
data/lib/langchain/tool/base.rb
CHANGED
@@ -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
|
88
|
+
# Returns the tool as a list of OpenAI formatted functions
|
95
89
|
#
|
96
90
|
# @return [Hash] tool as an OpenAI tool
|
97
|
-
def
|
98
|
-
|
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
|
-
#
|
10
|
-
#
|
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
|
-
#
|
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:
|
8
|
+
# Gem requirements:
|
9
|
+
# gem "google_search_results", "~> 2.0.0"
|
9
10
|
#
|
10
11
|
# Usage:
|
11
|
-
#
|
12
|
-
#
|
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
|
+
]
|
data/lib/langchain/tool/{ruby_code_interpreter.rb → ruby_code_interpreter/ruby_code_interpreter.rb}
RENAMED
@@ -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:
|
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: "
|
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:
|
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
|
|
data/lib/langchain/version.rb
CHANGED
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
|
-
#
|
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
|