langchainrb 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +3 -2
  4. data/lib/langchain/assistants/assistant.rb +75 -20
  5. data/lib/langchain/assistants/messages/base.rb +16 -0
  6. data/lib/langchain/assistants/messages/google_gemini_message.rb +90 -0
  7. data/lib/langchain/assistants/messages/openai_message.rb +74 -0
  8. data/lib/langchain/assistants/thread.rb +5 -5
  9. data/lib/langchain/llm/anthropic.rb +27 -49
  10. data/lib/langchain/llm/aws_bedrock.rb +30 -34
  11. data/lib/langchain/llm/azure.rb +6 -0
  12. data/lib/langchain/llm/base.rb +20 -1
  13. data/lib/langchain/llm/cohere.rb +38 -6
  14. data/lib/langchain/llm/google_gemini.rb +67 -0
  15. data/lib/langchain/llm/google_vertex_ai.rb +68 -112
  16. data/lib/langchain/llm/mistral_ai.rb +10 -19
  17. data/lib/langchain/llm/ollama.rb +23 -27
  18. data/lib/langchain/llm/openai.rb +20 -48
  19. data/lib/langchain/llm/parameters/chat.rb +51 -0
  20. data/lib/langchain/llm/response/base_response.rb +2 -2
  21. data/lib/langchain/llm/response/cohere_response.rb +16 -0
  22. data/lib/langchain/llm/response/google_gemini_response.rb +45 -0
  23. data/lib/langchain/llm/response/openai_response.rb +5 -1
  24. data/lib/langchain/llm/unified_parameters.rb +98 -0
  25. data/lib/langchain/loader.rb +6 -0
  26. data/lib/langchain/tool/base.rb +16 -6
  27. data/lib/langchain/tool/calculator/calculator.json +1 -1
  28. data/lib/langchain/tool/database/database.json +3 -3
  29. data/lib/langchain/tool/file_system/file_system.json +3 -3
  30. data/lib/langchain/tool/news_retriever/news_retriever.json +121 -0
  31. data/lib/langchain/tool/news_retriever/news_retriever.rb +132 -0
  32. data/lib/langchain/tool/ruby_code_interpreter/ruby_code_interpreter.json +1 -1
  33. data/lib/langchain/tool/vectorsearch/vectorsearch.json +1 -1
  34. data/lib/langchain/tool/weather/weather.json +1 -1
  35. data/lib/langchain/tool/wikipedia/wikipedia.json +1 -1
  36. data/lib/langchain/tool/wikipedia/wikipedia.rb +2 -2
  37. data/lib/langchain/utils/token_length/openai_validator.rb +6 -1
  38. data/lib/langchain/version.rb +1 -1
  39. data/lib/langchain.rb +3 -0
  40. metadata +22 -15
  41. data/lib/langchain/assistants/message.rb +0 -58
  42. data/lib/langchain/llm/response/google_vertex_ai_response.rb +0 -33
@@ -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,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Langchain::LLM
4
+ class GoogleGeminiResponse < BaseResponse
5
+ def initialize(raw_response, model: nil)
6
+ super(raw_response, model: model)
7
+ end
8
+
9
+ def chat_completion
10
+ raw_response.dig("candidates", 0, "content", "parts", 0, "text")
11
+ end
12
+
13
+ def role
14
+ raw_response.dig("candidates", 0, "content", "role")
15
+ end
16
+
17
+ def tool_calls
18
+ if raw_response.dig("candidates", 0, "content") && raw_response.dig("candidates", 0, "content", "parts", 0).has_key?("functionCall")
19
+ raw_response.dig("candidates", 0, "content", "parts")
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def embedding
26
+ embeddings.first
27
+ end
28
+
29
+ def embeddings
30
+ [raw_response.dig("predictions", 0, "embeddings", "values")]
31
+ end
32
+
33
+ def prompt_tokens
34
+ raw_response.dig("usageMetadata", "promptTokenCount")
35
+ end
36
+
37
+ def completion_tokens
38
+ raw_response.dig("usageMetadata", "candidatesTokenCount")
39
+ end
40
+
41
+ def total_tokens
42
+ raw_response.dig("usageMetadata", "totalTokenCount")
43
+ end
44
+ end
45
+ end
@@ -25,7 +25,11 @@ module Langchain::LLM
25
25
  end
26
26
 
27
27
  def tool_calls
28
- chat_completions&.dig(0, "message", "tool_calls")
28
+ if chat_completions.dig(0, "message").has_key?("tool_calls")
29
+ chat_completions.dig(0, "message", "tool_calls")
30
+ else
31
+ []
32
+ end
29
33
  end
30
34
 
31
35
  def embedding
@@ -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
@@ -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
@@ -3,13 +3,13 @@
3
3
  module Langchain::Tool
4
4
  # = Tools
5
5
  #
6
- # Tools are used by Agents to perform specific tasks. Basically anything is possible with enough code!
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 files
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 file in lib/langchain/tool/your_tool_name.rb
46
- # 2. Create a class in the file that inherits from {Langchain::Tool::Base}
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
@@ -66,11 +66,21 @@ module Langchain::Tool
66
66
 
67
67
  # Returns the tool as a list of OpenAI formatted functions
68
68
  #
69
- # @return [Hash] tool as an OpenAI tool
69
+ # @return [Array<Hash>] List of hashes representing the tool as OpenAI formatted functions
70
70
  def to_openai_tools
71
71
  method_annotations
72
72
  end
73
73
 
74
+ # Returns the tool as a list of Google Gemini formatted functions
75
+ #
76
+ # @return [Array<Hash>] List of hashes representing the tool as Google Gemini formatted functions
77
+ def to_google_gemini_tools
78
+ method_annotations.map do |annotation|
79
+ # Slice out only the content of the "function" key
80
+ annotation["function"]
81
+ end
82
+ end
83
+
74
84
  # Return tool's method annotations as JSON
75
85
  #
76
86
  # @return [Hash] Tool's method annotations
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "calculator-execute",
5
+ "name": "calculator__execute",
6
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
7
  "parameters": {
8
8
  "type": "object",
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "database-describe_tables",
5
+ "name": "database__describe_tables",
6
6
  "description": "Database Tool: Returns the schema for a list of tables",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -18,7 +18,7 @@
18
18
  }, {
19
19
  "type": "function",
20
20
  "function": {
21
- "name": "database-list_tables",
21
+ "name": "database__list_tables",
22
22
  "description": "Database Tool: Returns a list of tables in the database",
23
23
  "parameters": {
24
24
  "type": "object",
@@ -29,7 +29,7 @@
29
29
  }, {
30
30
  "type": "function",
31
31
  "function": {
32
- "name": "database-execute",
32
+ "name": "database__execute",
33
33
  "description": "Database Tool: Executes a SQL query and returns the results",
34
34
  "parameters": {
35
35
  "type": "object",
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "file_system-list_directory",
5
+ "name": "file_system__list_directory",
6
6
  "description": "File System Tool: Lists out the content of a specified directory",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -19,7 +19,7 @@
19
19
  {
20
20
  "type": "function",
21
21
  "function": {
22
- "name": "file_system-read_file",
22
+ "name": "file_system__read_file",
23
23
  "description": "File System Tool: Reads the contents of a file",
24
24
  "parameters": {
25
25
  "type": "object",
@@ -36,7 +36,7 @@
36
36
  {
37
37
  "type": "function",
38
38
  "function": {
39
- "name": "file_system-write_to_file",
39
+ "name": "file_system__write_to_file",
40
40
  "description": "File System Tool: Write content to a file",
41
41
  "parameters": {
42
42
  "type": "object",
@@ -0,0 +1,121 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "news_retriever__get_everything",
6
+ "description": "News Retriever: Search through millions of articles from over 150,000 large and small news sources and blogs.",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "q": {
11
+ "type": "string",
12
+ "description": "Keywords or phrases to search for in the article title and body. Surround phrases with quotes (\") for exact match. Alternatively you can use the AND / OR / NOT keywords, and optionally group these with parenthesis. Must be URL-encoded."
13
+ },
14
+ "search_in": {
15
+ "type": "string",
16
+ "description": "The fields to restrict your q search to.",
17
+ "enum": ["title", "description", "content"]
18
+ },
19
+ "sources": {
20
+ "type": "string",
21
+ "description": "A comma-seperated string of identifiers (maximum 20) for the news sources or blogs you want headlines from. Use the /sources endpoint to locate these programmatically or look at the sources index."
22
+ },
23
+ "domains": {
24
+ "type": "string",
25
+ "description": "A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to restrict the search to."
26
+ },
27
+ "exclude_domains": {
28
+ "type": "string",
29
+ "description": "A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to remove from the results."
30
+ },
31
+ "from": {
32
+ "type": "string",
33
+ "description": "A date and optional time for the oldest article allowed. This should be in ISO 8601 format."
34
+ },
35
+ "to": {
36
+ "type": "string",
37
+ "description": "A date and optional time for the newest article allowed. This should be in ISO 8601 format."
38
+ },
39
+ "language": {
40
+ "type": "string",
41
+ "description": "The 2-letter ISO-639-1 code of the language you want to get headlines for.",
42
+ "enum": ["ar", "de", "en", "es", "fr", "he", "it", "nl", "no", "pt", "ru", "sv", "ud", "zh"]
43
+ },
44
+ "sort_by": {
45
+ "type": "string",
46
+ "description": "The order to sort the articles in.",
47
+ "enum": ["relevancy", "popularity", "publishedAt"]
48
+ },
49
+ "page_size": {
50
+ "type": "integer",
51
+ "description": "The number of results to return per page (request). 5 is the default, 100 is the maximum."
52
+ },
53
+ "page": {
54
+ "type": "integer",
55
+ "description": "Use this to page through the results if the total results found is greater than the page size."
56
+ }
57
+ }
58
+ }
59
+ }
60
+ },
61
+ {
62
+ "type": "function",
63
+ "function": {
64
+ "name": "news_retriever__get_top_headlines",
65
+ "description": "News Retriever: Provides live top and breaking headlines for a country, specific category in a country, single source, or multiple sources. You can also search with keywords. Articles are sorted by the earliest date published first.",
66
+ "parameters": {
67
+ "type": "object",
68
+ "properties": {
69
+ "country": {
70
+ "type": "string",
71
+ "description": "The 2-letter ISO 3166-1 code of the country you want to get headlines for."
72
+ },
73
+ "category": {
74
+ "type": "string",
75
+ "description": "The category you want to get headlines for.",
76
+ "enum": ["business", "entertainment", "general", "health", "science", "sports", "technology"]
77
+ },
78
+ "q": {
79
+ "type": "string",
80
+ "description": "Keywords or a phrase to search for."
81
+ },
82
+ "page_size": {
83
+ "type": "integer",
84
+ "description": "The number of results to return per page (request). 5 is the default, 100 is the maximum."
85
+ },
86
+ "page": {
87
+ "type": "integer",
88
+ "description": "Use this to page through the results if the total results found is greater than the page size."
89
+ }
90
+ }
91
+ }
92
+ }
93
+ },
94
+ {
95
+ "type": "function",
96
+ "function": {
97
+ "name": "news_retriever__get_sources",
98
+ "description": "News Retriever: This endpoint returns the subset of news publishers that top headlines (/v2/top-headlines) are available from. It's mainly a convenience endpoint that you can use to keep track of the publishers available on the API, and you can pipe it straight through to your users.",
99
+ "parameters": {
100
+ "type": "object",
101
+ "properties": {
102
+ "country": {
103
+ "type": "string",
104
+ "description": "The 2-letter ISO 3166-1 code of the country you want to get headlines for. Default: all countries.",
105
+ "enum": ["ae", "ar", "at", "au", "be", "bg", "br", "ca", "ch", "cn", "co", "cu", "cz", "de", "eg", "fr", "gb", "gr", "hk", "hu", "id", "ie", "il", "in", "it", "jp", "kr", "lt", "lv", "ma", "mx", "my", "ng", "nl", "no", "nz", "ph", "pl", "pt", "ro", "rs", "ru", "sa", "se", "sg", "si", "sk", "th", "tr", "tw", "ua", "us", "ve", "za"]
106
+ },
107
+ "category": {
108
+ "type": "string",
109
+ "description": "The category you want to get headlines for. Default: all categories.",
110
+ "enum": ["business", "entertainment", "general", "health", "science", "sports", "technology"]
111
+ },
112
+ "language": {
113
+ "type": "string",
114
+ "description": "The 2-letter ISO-639-1 code of the language you want to get headlines for.",
115
+ "enum": ["ar", "de", "en", "es", "fr", "he", "it", "nl", "no", "pt", "ru", "sv", "ud", "zh"]
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ]
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Langchain::Tool
4
+ class NewsRetriever < Base
5
+ #
6
+ # A tool that retrieves latest news from various sources via https://newsapi.org/.
7
+ # An API key needs to be obtained from https://newsapi.org/ to use this tool.
8
+ #
9
+ # Usage:
10
+ # news_retriever = Langchain::Tool::NewsRetriever.new(api_key: ENV["NEWS_API_KEY"])
11
+ #
12
+ NAME = "news_retriever"
13
+ ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path
14
+
15
+ def initialize(api_key: ENV["NEWS_API_KEY"])
16
+ @api_key = api_key
17
+ end
18
+
19
+ # Retrieve all news
20
+ #
21
+ # @param q [String] Keywords or phrases to search for in the article title and body.
22
+ # @param search_in [String] The fields to restrict your q search to. The possible options are: title, description, content.
23
+ # @param sources [String] A comma-seperated string of identifiers (maximum 20) for the news sources or blogs you want headlines from. Use the /sources endpoint to locate these programmatically or look at the sources index.
24
+ # @param domains [String] A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to restrict the search to.
25
+ # @param exclude_domains [String] A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to remove from the results.
26
+ # @param from [String] A date and optional time for the oldest article allowed. This should be in ISO 8601 format.
27
+ # @param to [String] A date and optional time for the newest article allowed. This should be in ISO 8601 format.
28
+ # @param language [String] The 2-letter ISO-639-1 code of the language you want to get headlines for. Possible options: ar, de, en, es, fr, he, it, nl, no, pt, ru, se, ud, zh.
29
+ # @param sort_by [String] The order to sort the articles in. Possible options: relevancy, popularity, publishedAt.
30
+ # @param page_size [Integer] The number of results to return per page. 20 is the API's default, 100 is the maximum. Our default is 5.
31
+ # @param page [Integer] Use this to page through the results.
32
+ #
33
+ # @return [String] JSON response
34
+ def get_everything(
35
+ q: nil,
36
+ search_in: nil,
37
+ sources: nil,
38
+ domains: nil,
39
+ exclude_domains: nil,
40
+ from: nil,
41
+ to: nil,
42
+ language: nil,
43
+ sort_by: nil,
44
+ page_size: 5, # The API default is 20 but that's too many.
45
+ page: nil
46
+ )
47
+ Langchain.logger.info("Retrieving all news", for: self.class)
48
+
49
+ params = {apiKey: @api_key}
50
+ params[:q] = q if q
51
+ params[:searchIn] = search_in if search_in
52
+ params[:sources] = sources if sources
53
+ params[:domains] = domains if domains
54
+ params[:excludeDomains] = exclude_domains if exclude_domains
55
+ params[:from] = from if from
56
+ params[:to] = to if to
57
+ params[:language] = language if language
58
+ params[:sortBy] = sort_by if sort_by
59
+ params[:pageSize] = page_size if page_size
60
+ params[:page] = page if page
61
+
62
+ send_request(path: "everything", params: params)
63
+ end
64
+
65
+ # Retrieve top headlines
66
+ #
67
+ # @param country [String] The 2-letter ISO 3166-1 code of the country you want to get headlines for. Possible options: ae, ar, at, au, be, bg, br, ca, ch, cn, co, cu, cz, de, eg, fr, gb, gr, hk, hu, id, ie, il, in, it, jp, kr, lt, lv, ma, mx, my, ng, nl, no, nz, ph, pl, pt, ro, rs, ru, sa, se, sg, si, sk, th, tr, tw, ua, us, ve, za.
68
+ # @param category [String] The category you want to get headlines for. Possible options: business, entertainment, general, health, science, sports, technology.
69
+ # @param sources [String] A comma-seperated string of identifiers for the news sources or blogs you want headlines from. Use the /sources endpoint to locate these programmatically.
70
+ # @param q [String] Keywords or a phrase to search for.
71
+ # @param page_size [Integer] The number of results to return per page. 20 is the API's default, 100 is the maximum. Our default is 5.
72
+ # @param page [Integer] Use this to page through the results.
73
+ #
74
+ # @return [String] JSON response
75
+ def get_top_headlines(
76
+ country: nil,
77
+ category: nil,
78
+ sources: nil,
79
+ q: nil,
80
+ page_size: 5,
81
+ page: nil
82
+ )
83
+ Langchain.logger.info("Retrieving top news headlines", for: self.class)
84
+
85
+ params = {apiKey: @api_key}
86
+ params[:country] = country if country
87
+ params[:category] = category if category
88
+ params[:sources] = sources if sources
89
+ params[:q] = q if q
90
+ params[:pageSize] = page_size if page_size
91
+ params[:page] = page if page
92
+
93
+ send_request(path: "top-headlines", params: params)
94
+ end
95
+
96
+ # Retrieve news sources
97
+ #
98
+ # @param category [String] The category you want to get headlines for. Possible options: business, entertainment, general, health, science, sports, technology.
99
+ # @param language [String] The 2-letter ISO-639-1 code of the language you want to get headlines for. Possible options: ar, de, en, es, fr, he, it, nl, no, pt, ru, se, ud, zh.
100
+ # @param country [String] The 2-letter ISO 3166-1 code of the country you want to get headlines for. Possible options: ae, ar, at, au, be, bg, br, ca, ch, cn, co, cu, cz, de, eg, fr, gb, gr, hk, hu, id, ie, il, in, it, jp, kr, lt, lv, ma, mx, my, ng, nl, no, nz, ph, pl, pt, ro, rs, ru, sa, se, sg, si, sk, th, tr, tw, ua, us, ve, za.
101
+ #
102
+ # @return [String] JSON response
103
+ def get_sources(
104
+ category: nil,
105
+ language: nil,
106
+ country: nil
107
+ )
108
+ Langchain.logger.info("Retrieving news sources", for: self.class)
109
+
110
+ params = {apiKey: @api_key}
111
+ params[:country] = country if country
112
+ params[:category] = category if category
113
+ params[:language] = language if language
114
+
115
+ send_request(path: "top-headlines/sources", params: params)
116
+ end
117
+
118
+ private
119
+
120
+ def send_request(path:, params:)
121
+ uri = URI.parse("https://newsapi.org/v2/#{path}?#{URI.encode_www_form(params)}")
122
+ http = Net::HTTP.new(uri.host, uri.port)
123
+ http.use_ssl = true
124
+
125
+ request = Net::HTTP::Get.new(uri.request_uri)
126
+ request["Content-Type"] = "application/json"
127
+
128
+ response = http.request(request)
129
+ response.body
130
+ end
131
+ end
132
+ end
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "ruby_code_interpreter-execute",
5
+ "name": "ruby_code_interpreter__execute",
6
6
  "description": "Executes Ruby code in a sandboxes environment.",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "vectorsearch-similarity_search",
5
+ "name": "vectorsearch__similarity_search",
6
6
  "description": "Vectorsearch: Retrieves relevant document for the query",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "weather-execute",
5
+ "name": "weather__execute",
6
6
  "description": "Returns current weather for a city",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": "function",
4
4
  "function": {
5
- "name": "wikipedia-execute",
5
+ "name": "wikipedia__execute",
6
6
  "description": "Executes Wikipedia API search and returns the answer",
7
7
  "parameters": {
8
8
  "type": "object",
@@ -9,8 +9,8 @@ module Langchain::Tool
9
9
  # gem "wikipedia-client", "~> 1.17.0"
10
10
  #
11
11
  # Usage:
12
- # weather = Langchain::Tool::Wikipedia.new
13
- # weather.execute(input: "The Roman Empire")
12
+ # wikipedia = Langchain::Tool::Wikipedia.new
13
+ # wikipedia.execute(input: "The Roman Empire")
14
14
  #
15
15
  NAME = "wikipedia"
16
16
  ANNOTATIONS_PATH = Langchain.root.join("./langchain/tool/#{NAME}/#{NAME}.json").to_path