tavily 0.1.0

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.
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "object"
4
+
5
+ module Tavily
6
+ # Credit usage information, present when +include_usage: true+ is requested.
7
+ class Usage < Object
8
+ # @return [Integer, nil] number of API credits consumed by the request.
9
+ attribute :credits
10
+ end
11
+
12
+ # An image associated with a search result. Tavily returns images either as
13
+ # bare URL strings or as objects with a description; this normalizes both.
14
+ class Image < Object
15
+ # @return [String, nil] image URL.
16
+ attribute :url
17
+ # @return [String, nil] generated description (when image descriptions requested).
18
+ attribute :description
19
+ end
20
+
21
+ # A single web result from {Client#search}.
22
+ class SearchResult < Object
23
+ # @return [String, nil] page title.
24
+ attribute :title
25
+ # @return [String, nil] result URL.
26
+ attribute :url
27
+ # @return [String, nil] short relevant snippet.
28
+ attribute :content
29
+ # @return [Float, nil] relevance score (0.0–1.0).
30
+ attribute :score
31
+ # @return [String, nil] full cleaned page content (when raw content requested).
32
+ attribute :raw_content
33
+ # @return [String, nil] favicon URL (when +include_favicon: true+).
34
+ attribute :favicon
35
+ # @return [String, nil] publication date (present for +topic: "news"+).
36
+ attribute :published_date
37
+ end
38
+
39
+ # Mixin adding +usage+/+credits+/+request_id+/+response_time+ accessors shared
40
+ # by every top-level response.
41
+ module Envelope
42
+ def self.included(base)
43
+ base.attribute :response_time
44
+ base.attribute :request_id
45
+ end
46
+
47
+ # @return [Usage, nil] credit usage details (when +include_usage: true+).
48
+ def usage
49
+ raw = self["usage"]
50
+ raw.is_a?(Hash) ? Usage.new(raw) : nil
51
+ end
52
+
53
+ # @return [Integer, nil] convenience accessor for +usage.credits+.
54
+ def credits
55
+ usage&.credits
56
+ end
57
+ end
58
+
59
+ # Response from {Client#search}.
60
+ class SearchResponse < Object
61
+ include Envelope
62
+
63
+ # @return [String] the executed query.
64
+ attribute :query
65
+ # @return [String, nil] LLM-generated answer (when +include_answer+ requested).
66
+ attribute :answer
67
+ # @return [Array, nil] suggested follow-up questions, if any.
68
+ attribute :follow_up_questions
69
+ # @return [Hash, nil] parameters auto-selected by Tavily (when +auto_parameters: true+).
70
+ attribute :auto_parameters
71
+ # @return [Array<SearchResult>] ranked results.
72
+ attribute :results, wrap: SearchResult, collection: true
73
+
74
+ # @return [Array<Image>] related images (normalizes string and object forms).
75
+ def images
76
+ Array(self["images"]).map do |img|
77
+ img.is_a?(Hash) ? Image.new(img) : Image.new("url" => img)
78
+ end
79
+ end
80
+
81
+ # @return [Array<String>] convenience list of result URLs.
82
+ def urls
83
+ results.map(&:url)
84
+ end
85
+ end
86
+
87
+ # A single successfully extracted page from {Client#extract}.
88
+ class ExtractResult < Object
89
+ # @return [String, nil] the extracted URL.
90
+ attribute :url
91
+ # @return [String, nil] extracted content (markdown or text).
92
+ attribute :raw_content
93
+ # @return [Array<String>] image URLs (when +include_images: true+).
94
+ attribute :images
95
+ # @return [String, nil] favicon URL (when +include_favicon: true+).
96
+ attribute :favicon
97
+ end
98
+
99
+ # A URL that failed extraction.
100
+ class FailedResult < Object
101
+ # @return [String, nil] the URL that failed.
102
+ attribute :url
103
+ # @return [String, nil] reason for the failure.
104
+ attribute :error
105
+ end
106
+
107
+ # Response from {Client#extract}.
108
+ class ExtractResponse < Object
109
+ include Envelope
110
+
111
+ # @return [Array<ExtractResult>] successfully extracted pages.
112
+ attribute :results, wrap: ExtractResult, collection: true
113
+ # @return [Array<FailedResult>] URLs that could not be extracted.
114
+ attribute :failed_results, wrap: FailedResult, collection: true
115
+ end
116
+
117
+ # A single page discovered by {Client#crawl}.
118
+ class CrawlResult < Object
119
+ # @return [String, nil] page URL.
120
+ attribute :url
121
+ # @return [String, nil] extracted content (markdown or text).
122
+ attribute :raw_content
123
+ # @return [String, nil] favicon URL (when +include_favicon: true+).
124
+ attribute :favicon
125
+ end
126
+
127
+ # Response from {Client#crawl}.
128
+ class CrawlResponse < Object
129
+ include Envelope
130
+
131
+ # @return [String, nil] the root URL that was crawled.
132
+ attribute :base_url
133
+ # @return [Array<CrawlResult>] crawled pages.
134
+ attribute :results, wrap: CrawlResult, collection: true
135
+ end
136
+
137
+ # Response from {Client#map}.
138
+ class MapResponse < Object
139
+ include Envelope
140
+
141
+ # @return [String, nil] the root URL that was mapped.
142
+ attribute :base_url
143
+ # @return [Array<String>] discovered URLs.
144
+ attribute :results
145
+ end
146
+
147
+ # A source cited by a research task.
148
+ class ResearchSource < Object
149
+ # @return [String, nil] source title.
150
+ attribute :title
151
+ # @return [String, nil] source URL.
152
+ attribute :url
153
+ # @return [String, nil] favicon URL.
154
+ attribute :favicon
155
+ end
156
+
157
+ # A research task, returned by {Client#research} (status +pending+) and by
158
+ # {Client#research_task} / {Client#wait_for_research} (with the final result).
159
+ class ResearchTask < Object
160
+ include Envelope
161
+
162
+ # @return [String, nil] research task id (use to poll for results).
163
+ attribute :request_id
164
+ # @return [String, nil] creation timestamp (ISO 8601).
165
+ attribute :created_at
166
+ # @return [String, nil] one of "pending", "in_progress", "completed", "failed".
167
+ attribute :status
168
+ # @return [String, nil] echo of the research input.
169
+ attribute :input
170
+ # @return [String, nil] the model used ("mini", "pro", or resolved from "auto").
171
+ attribute :model
172
+ # @return [String, Hash, nil] the final report (String, or Hash when +output_schema+ used).
173
+ attribute :content
174
+ # @return [Array<ResearchSource>] sources used in the research.
175
+ attribute :sources, wrap: ResearchSource, collection: true
176
+
177
+ # @return [Boolean] whether the task finished successfully.
178
+ def completed?
179
+ status == "completed"
180
+ end
181
+
182
+ # @return [Boolean] whether the task failed.
183
+ def failed?
184
+ status == "failed"
185
+ end
186
+
187
+ # @return [Boolean] whether the task is still running or queued.
188
+ def pending?
189
+ %w[pending in_progress].include?(status)
190
+ end
191
+ end
192
+
193
+ # A single Server-Sent Event emitted by streaming research
194
+ # ({Client#research} with a block). +data+ is the parsed JSON payload when
195
+ # possible, otherwise the raw string.
196
+ ResearchEvent = Struct.new(:event, :data, keyword_init: true)
197
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tavily
4
+ VERSION = "0.1.0"
5
+ end
data/lib/tavily.rb ADDED
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tavily/version"
4
+ require_relative "tavily/errors"
5
+ require_relative "tavily/configuration"
6
+ require_relative "tavily/object"
7
+ require_relative "tavily/responses"
8
+ require_relative "tavily/connection"
9
+ require_relative "tavily/client"
10
+
11
+ # Ruby client for the {https://docs.tavily.com Tavily} web search, extract,
12
+ # crawl, map, and research API.
13
+ #
14
+ # @example One-off call using the global configuration
15
+ # Tavily.configure { |c| c.api_key = ENV["TAVILY_API_KEY"] }
16
+ # Tavily.search("latest ruby release").results.first.url
17
+ #
18
+ # @example Dedicated client
19
+ # client = Tavily::Client.new(api_key: "tvly-...")
20
+ # client.extract("https://example.com")
21
+ module Tavily
22
+ class << self
23
+ # The global configuration shared by {Tavily.search} and friends, and used
24
+ # as the default for new {Client} instances.
25
+ # @return [Configuration]
26
+ def configuration
27
+ @configuration ||= Configuration.new
28
+ end
29
+
30
+ # Configure the library.
31
+ # @yieldparam config [Configuration]
32
+ # @return [Configuration]
33
+ def configure
34
+ yield(configuration) if block_given?
35
+ reset_default_client!
36
+ configuration
37
+ end
38
+
39
+ # Reset the global configuration to defaults (re-reads ENV). Mainly useful
40
+ # in tests.
41
+ # @return [Configuration]
42
+ def reset_configuration!
43
+ @configuration = Configuration.new
44
+ reset_default_client!
45
+ @configuration
46
+ end
47
+
48
+ # A process-wide {Client} built from the global {.configuration}.
49
+ # @return [Client]
50
+ def default_client
51
+ @default_client ||= Client.new
52
+ end
53
+
54
+ # @api private
55
+ def reset_default_client!
56
+ @default_client = nil
57
+ end
58
+
59
+ # @see Client#search
60
+ def search(...) = default_client.search(...)
61
+ # @see Client#qna_search
62
+ def qna_search(...) = default_client.qna_search(...)
63
+ # @see Client#search_context
64
+ def search_context(...) = default_client.search_context(...)
65
+ # @see Client#extract
66
+ def extract(...) = default_client.extract(...)
67
+ # @see Client#crawl
68
+ def crawl(...) = default_client.crawl(...)
69
+ # @see Client#map
70
+ def map(...) = default_client.map(...)
71
+ # @see Client#research
72
+ def research(...) = default_client.research(...)
73
+ # @see Client#research_task
74
+ def research_task(...) = default_client.research_task(...)
75
+ # @see Client#wait_for_research
76
+ def wait_for_research(...) = default_client.wait_for_research(...)
77
+ end
78
+ end
@@ -0,0 +1,107 @@
1
+ module Tavily
2
+ class Client
3
+ DEFAULT_POLL_INTERVAL: Float
4
+ DEFAULT_POLL_TIMEOUT: Integer
5
+
6
+ attr_reader config: Configuration
7
+
8
+ def initialize: (?api_key: String?, **untyped) -> void
9
+
10
+ def search: (
11
+ String query,
12
+ ?search_depth: String?,
13
+ ?topic: String?,
14
+ ?max_results: Integer?,
15
+ ?chunks_per_source: Integer?,
16
+ ?time_range: String?,
17
+ ?days: Integer?,
18
+ ?start_date: String?,
19
+ ?end_date: String?,
20
+ ?include_answer: (bool | String)?,
21
+ ?include_raw_content: (bool | String)?,
22
+ ?include_images: bool?,
23
+ ?include_image_descriptions: bool?,
24
+ ?include_favicon: bool?,
25
+ ?include_domains: Array[String]?,
26
+ ?exclude_domains: Array[String]?,
27
+ ?country: String?,
28
+ ?auto_parameters: bool?,
29
+ ?include_usage: bool?,
30
+ **untyped extra
31
+ ) -> SearchResponse
32
+
33
+ def qna_search: (String query, **untyped options) -> String?
34
+
35
+ def search_context: (String query, ?max_tokens: Integer, **untyped options) -> String
36
+
37
+ def extract: (
38
+ String | Array[String] urls,
39
+ ?query: String?,
40
+ ?chunks_per_source: Integer?,
41
+ ?extract_depth: String?,
42
+ ?include_images: bool?,
43
+ ?include_favicon: bool?,
44
+ ?format: String?,
45
+ ?timeout: Numeric?,
46
+ ?include_usage: bool?,
47
+ **untyped extra
48
+ ) -> ExtractResponse
49
+
50
+ def crawl: (
51
+ String url,
52
+ ?instructions: String?,
53
+ ?chunks_per_source: Integer?,
54
+ ?max_depth: Integer?,
55
+ ?max_breadth: Integer?,
56
+ ?limit: Integer?,
57
+ ?select_paths: Array[String]?,
58
+ ?select_domains: Array[String]?,
59
+ ?exclude_paths: Array[String]?,
60
+ ?exclude_domains: Array[String]?,
61
+ ?allow_external: bool?,
62
+ ?include_images: bool?,
63
+ ?extract_depth: String?,
64
+ ?format: String?,
65
+ ?include_favicon: bool?,
66
+ ?timeout: Numeric?,
67
+ ?include_usage: bool?,
68
+ **untyped extra
69
+ ) -> CrawlResponse
70
+
71
+ def map: (
72
+ String url,
73
+ ?instructions: String?,
74
+ ?max_depth: Integer?,
75
+ ?max_breadth: Integer?,
76
+ ?limit: Integer?,
77
+ ?select_paths: Array[String]?,
78
+ ?select_domains: Array[String]?,
79
+ ?exclude_paths: Array[String]?,
80
+ ?exclude_domains: Array[String]?,
81
+ ?allow_external: bool?,
82
+ ?timeout: Numeric?,
83
+ ?include_usage: bool?,
84
+ **untyped extra
85
+ ) -> MapResponse
86
+
87
+ def research: (
88
+ String input,
89
+ ?model: String?,
90
+ ?output_schema: Hash[untyped, untyped]?,
91
+ ?citation_format: String?,
92
+ ?include_domains: Array[String]?,
93
+ ?exclude_domains: Array[String]?,
94
+ ?output_length: String?,
95
+ ?files: Array[Hash[untyped, untyped]]?,
96
+ **untyped extra
97
+ ) ?{ (ResearchEvent) -> void } -> ResearchTask?
98
+
99
+ def research_task: (String request_id) -> ResearchTask
100
+
101
+ def wait_for_research: (
102
+ String request_id,
103
+ ?poll_interval: Numeric,
104
+ ?timeout: Numeric
105
+ ) ?{ (ResearchTask) -> void } -> ResearchTask
106
+ end
107
+ end
@@ -0,0 +1,23 @@
1
+ module Tavily
2
+ class Configuration
3
+ DEFAULT_BASE_URL: String
4
+ DEFAULT_TIMEOUT: Integer
5
+ DEFAULT_OPEN_TIMEOUT: Integer
6
+ DEFAULT_MAX_RETRIES: Integer
7
+ DEFAULT_RETRY_BASE_DELAY: Float
8
+
9
+ attr_accessor api_key: String?
10
+ attr_accessor base_url: String
11
+ attr_accessor timeout: Numeric
12
+ attr_accessor open_timeout: Numeric
13
+ attr_accessor max_retries: Integer
14
+ attr_accessor retry_base_delay: Numeric
15
+ attr_accessor proxy: String?
16
+ attr_accessor ca_file: String?
17
+ attr_accessor logger: untyped
18
+ attr_accessor user_agent: String
19
+
20
+ def initialize: () -> void
21
+ def to_h: () -> Hash[Symbol, untyped]
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ module Tavily
2
+ class Connection
3
+ RETRIABLE_STATUSES: Array[Integer]
4
+ RETRIABLE_TIMEOUTS: Array[Class]
5
+ RETRIABLE_NETWORK: Array[Class]
6
+
7
+ def initialize: (Configuration config) -> void
8
+ def post: (String path, ?Hash[untyped, untyped] body) -> untyped
9
+ def get: (String path, ?Hash[untyped, untyped] params) -> untyped
10
+ def stream: (String path, ?Hash[untyped, untyped] body) { (ResearchEvent) -> void } -> nil
11
+ end
12
+ end
@@ -0,0 +1,57 @@
1
+ module Tavily
2
+ class Error < StandardError
3
+ end
4
+
5
+ class ConfigurationError < Error
6
+ end
7
+
8
+ class TimeoutError < Error
9
+ end
10
+
11
+ class ConnectionError < Error
12
+ end
13
+
14
+ class APIError < Error
15
+ attr_reader status: Integer?
16
+ attr_reader body: untyped
17
+ attr_reader request_id: String?
18
+
19
+ def initialize: (?String? message, ?status: Integer?, ?body: untyped, ?request_id: String?) -> void
20
+ end
21
+
22
+ class BadRequestError < APIError
23
+ end
24
+
25
+ class AuthenticationError < APIError
26
+ end
27
+
28
+ class ForbiddenError < APIError
29
+ end
30
+
31
+ class NotFoundError < APIError
32
+ end
33
+
34
+ class UnprocessableEntityError < APIError
35
+ end
36
+
37
+ class RateLimitError < APIError
38
+ end
39
+
40
+ class UsageLimitError < APIError
41
+ end
42
+
43
+ class PlanLimitError < UsageLimitError
44
+ end
45
+
46
+ class PayAsYouGoLimitError < UsageLimitError
47
+ end
48
+
49
+ class ServerError < APIError
50
+ end
51
+
52
+ module Errors
53
+ STATUS_MAP: Hash[Integer, Class]
54
+
55
+ def self.class_for: (Integer status) -> Class
56
+ end
57
+ end
@@ -0,0 +1,18 @@
1
+ module Tavily
2
+ class Object
3
+ attr_reader attributes: Hash[String, untyped]
4
+
5
+ def self.attribute: (Symbol name, ?key: String, ?wrap: (Class | String)?, ?collection: bool) -> void
6
+
7
+ def initialize: (?untyped attributes) -> void
8
+ def []: (String | Symbol key) -> untyped
9
+ def dig: (*(String | Symbol) keys) -> untyped
10
+ def key?: (String | Symbol key) -> bool
11
+ def to_h: () -> Hash[String, untyped]
12
+ def to_hash: () -> Hash[String, untyped]
13
+ def ==: (untyped other) -> bool
14
+ def eql?: (untyped other) -> bool
15
+ def hash: () -> Integer
16
+ def inspect: () -> String
17
+ end
18
+ end
@@ -0,0 +1,108 @@
1
+ module Tavily
2
+ class Usage < Object
3
+ def credits: () -> Integer?
4
+ end
5
+
6
+ class Image < Object
7
+ def url: () -> String?
8
+ def description: () -> String?
9
+ end
10
+
11
+ class SearchResult < Object
12
+ def title: () -> String?
13
+ def url: () -> String?
14
+ def content: () -> String?
15
+ def score: () -> Float?
16
+ def raw_content: () -> String?
17
+ def favicon: () -> String?
18
+ def published_date: () -> String?
19
+ end
20
+
21
+ module Envelope
22
+ def self.included: (untyped base) -> void
23
+
24
+ def response_time: () -> Numeric?
25
+ def request_id: () -> String?
26
+ def usage: () -> Usage?
27
+ def credits: () -> Integer?
28
+ end
29
+
30
+ class SearchResponse < Object
31
+ include Envelope
32
+
33
+ def query: () -> String?
34
+ def answer: () -> String?
35
+ def follow_up_questions: () -> Array[untyped]?
36
+ def auto_parameters: () -> Hash[String, untyped]?
37
+ def results: () -> Array[SearchResult]
38
+ def images: () -> Array[Image]
39
+ def urls: () -> Array[String?]
40
+ end
41
+
42
+ class ExtractResult < Object
43
+ def url: () -> String?
44
+ def raw_content: () -> String?
45
+ def images: () -> Array[String]?
46
+ def favicon: () -> String?
47
+ end
48
+
49
+ class FailedResult < Object
50
+ def url: () -> String?
51
+ def error: () -> String?
52
+ end
53
+
54
+ class ExtractResponse < Object
55
+ include Envelope
56
+
57
+ def results: () -> Array[ExtractResult]
58
+ def failed_results: () -> Array[FailedResult]
59
+ end
60
+
61
+ class CrawlResult < Object
62
+ def url: () -> String?
63
+ def raw_content: () -> String?
64
+ def favicon: () -> String?
65
+ end
66
+
67
+ class CrawlResponse < Object
68
+ include Envelope
69
+
70
+ def base_url: () -> String?
71
+ def results: () -> Array[CrawlResult]
72
+ end
73
+
74
+ class MapResponse < Object
75
+ include Envelope
76
+
77
+ def base_url: () -> String?
78
+ def results: () -> Array[String]?
79
+ end
80
+
81
+ class ResearchSource < Object
82
+ def title: () -> String?
83
+ def url: () -> String?
84
+ def favicon: () -> String?
85
+ end
86
+
87
+ class ResearchTask < Object
88
+ include Envelope
89
+
90
+ def request_id: () -> String?
91
+ def created_at: () -> String?
92
+ def status: () -> String?
93
+ def input: () -> String?
94
+ def model: () -> String?
95
+ def content: () -> (String | Hash[String, untyped])?
96
+ def sources: () -> Array[ResearchSource]
97
+ def completed?: () -> bool
98
+ def failed?: () -> bool
99
+ def pending?: () -> bool
100
+ end
101
+
102
+ class ResearchEvent
103
+ attr_accessor event: String?
104
+ attr_accessor data: untyped
105
+
106
+ def self.new: (?event: String?, ?data: untyped) -> instance
107
+ end
108
+ end
data/sig/tavily.rbs ADDED
@@ -0,0 +1,19 @@
1
+ module Tavily
2
+ VERSION: String
3
+
4
+ def self.configuration: () -> Configuration
5
+ def self.configure: () ?{ (Configuration) -> void } -> Configuration
6
+ def self.reset_configuration!: () -> Configuration
7
+ def self.default_client: () -> Client
8
+ def self.reset_default_client!: () -> void
9
+
10
+ def self.search: (*untyped, **untyped) -> SearchResponse
11
+ def self.qna_search: (*untyped, **untyped) -> String?
12
+ def self.search_context: (*untyped, **untyped) -> String
13
+ def self.extract: (*untyped, **untyped) -> ExtractResponse
14
+ def self.crawl: (*untyped, **untyped) -> CrawlResponse
15
+ def self.map: (*untyped, **untyped) -> MapResponse
16
+ def self.research: (*untyped, **untyped) ?{ (ResearchEvent) -> void } -> ResearchTask?
17
+ def self.research_task: (*untyped, **untyped) -> ResearchTask
18
+ def self.wait_for_research: (*untyped, **untyped) ?{ (ResearchTask) -> void } -> ResearchTask
19
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tavily
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ned
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |-
13
+ A lightweight, dependency-free Ruby client for the Tavily API. The web access
14
+ layer built for LLMs and AI agents. Wraps the search, extract, crawl, map, and
15
+ research endpoints with typed response objects, automatic retries with backoff,
16
+ streaming research, and granular error handling.
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - LICENSE.txt
23
+ - README.md
24
+ - lib/tavily.rb
25
+ - lib/tavily/client.rb
26
+ - lib/tavily/configuration.rb
27
+ - lib/tavily/connection.rb
28
+ - lib/tavily/errors.rb
29
+ - lib/tavily/object.rb
30
+ - lib/tavily/responses.rb
31
+ - lib/tavily/version.rb
32
+ - sig/tavily.rbs
33
+ - sig/tavily/client.rbs
34
+ - sig/tavily/configuration.rbs
35
+ - sig/tavily/connection.rbs
36
+ - sig/tavily/errors.rbs
37
+ - sig/tavily/object.rbs
38
+ - sig/tavily/responses.rbs
39
+ homepage: https://github.com/main-path/tavily
40
+ licenses:
41
+ - MIT
42
+ metadata:
43
+ source_code_uri: https://github.com/main-path/tavily
44
+ changelog_uri: https://github.com/main-path/tavily/blob/main/CHANGELOG.md
45
+ documentation_uri: https://docs.tavily.com/
46
+ bug_tracker_uri: https://github.com/main-path/tavily/issues
47
+ rubygems_mfa_required: 'true'
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 3.1.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.6.9
63
+ specification_version: 4
64
+ summary: Ruby client for the Tavily search, extract, crawl, map, and research API.
65
+ test_files: []