turbopuffer 2.1.0 → 2.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20d0c90e03716bcf7ca9387385505eb4bd4711888f16eb0d3bde30d70ad0829a
4
- data.tar.gz: 29b6153b4c7250a63170be4c7b1010933ef7c96e7817fd78de6d4790fed8a481
3
+ metadata.gz: a3a51779391cbefbadc2c92d4da69e9f2b8a16db31b09626fc610d979f8317af
4
+ data.tar.gz: f814addde33fea46dfea6c616ab8f71c34a4813a7f53283bdd3b04765ea9f91b
5
5
  SHA512:
6
- metadata.gz: b7243b9b3134d2fa3741ed94b79c5813f4d23a5f106d561865a8a9e1891ac76c7cb0d66088bbb3e2b9f0f1970ed023bffc06a9c98059ac8af9e0b8f544b0249d
7
- data.tar.gz: f249a2b3afa1092d5bab4ea3510ee6de24719b8e61fbbcc5975f90e6d6ecbc002298283454f0f1eccf9c313f9f7def328b6f508df894f9a852ae3759d8b6ac66
6
+ metadata.gz: 66b621f09d12e2ae0540a69f163c596063b59c3a4df34416cd9c48330f167065af3ee4e1292d1d954adcfc7796b1d1a46fd023b50681f286d81e1984535e5880
7
+ data.tar.gz: 9b77397676c00954fd6ee3bad008eeedf6af798d41718d636841b9e12c35ab98caa434acaee6f157e006d9d08aa6491df57943ebfe8fa846fbcc131102a8d957
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.3.0 (2026-06-16)
4
+
5
+ Full Changelog: [v2.2.0...v2.3.0](https://github.com/turbopuffer/turbopuffer-ruby/compare/v2.2.0...v2.3.0)
6
+
7
+ ### Features
8
+
9
+ * tpuf-engine: support dest_encryption in copy_from_namespace ([ef8ce32](https://github.com/turbopuffer/turbopuffer-ruby/commit/ef8ce322607fe8fd30b259d5012582b776ec1b09))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **client:** send content-type header for requests with an omitted optional body ([d2c5ed1](https://github.com/turbopuffer/turbopuffer-ruby/commit/d2c5ed1ec19aa3c371c1bce215f9b77ac5910dd7))
15
+
16
+
17
+ ### Documentation
18
+
19
+ * rename /docs/overview to /docs/api-overview ([c049a0c](https://github.com/turbopuffer/turbopuffer-ruby/commit/c049a0c4a712f9de2081da5f387a8036acc04fcf))
20
+
21
+ ## 2.2.0 (2026-06-08)
22
+
23
+ Full Changelog: [v2.1.0...v2.2.0](https://github.com/turbopuffer/turbopuffer-ruby/compare/v2.1.0...v2.2.0)
24
+
25
+ ### Features
26
+
27
+ * stainless: update sdks to support case-insensitive fuzzy filter ([d02bb79](https://github.com/turbopuffer/turbopuffer-ruby/commit/d02bb79d809f3b2285020f3aac4a3441ac1e38b2))
28
+ * transparent async polling ([#61](https://github.com/turbopuffer/turbopuffer-ruby/issues/61)) ([d93c499](https://github.com/turbopuffer/turbopuffer-ruby/commit/d93c49924d0df4bb4be9935f2090ce6fa26da18e))
29
+
3
30
  ## 2.1.0 (2026-06-03)
4
31
 
5
32
  Full Changelog: [v2.1.0-alpha.1...v2.1.0](https://github.com/turbopuffer/turbopuffer-ruby/compare/v2.1.0-alpha.1...v2.1.0)
data/README.md CHANGED
@@ -17,7 +17,7 @@ Use the turbopuffer MCP Server to enable AI assistants to interact with this API
17
17
 
18
18
  Documentation for releases of this gem can be found [on RubyDoc](https://gemdocs.org/gems/turbopuffer).
19
19
 
20
- The REST API documentation can be found at [turbopuffer.com/docs/overview](https://turbopuffer.com/docs/overview).
20
+ The REST API documentation can be found at [turbopuffer.com/docs/api-overview](https://turbopuffer.com/docs/api-overview).
21
21
 
22
22
  ## Installation
23
23
 
@@ -26,7 +26,7 @@ To use this gem, install via Bundler by adding the following to your application
26
26
  <!-- x-release-please-start-version -->
27
27
 
28
28
  ```ruby
29
- gem "turbopuffer", "~> 2.1.0"
29
+ gem "turbopuffer", "~> 2.3.0"
30
30
  ```
31
31
 
32
32
  <!-- x-release-please-end -->
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Turbopuffer
4
+ module Internal
5
+ # Support for transparent polling of async tpuf APIs.
6
+ #
7
+ # Every API request is stamped with `Prefer: respond-async`. If the server
8
+ # applies the preference (i.e. responds with `202 Accepted` +
9
+ # `preference-applied: respond-async`) the SDK polls that URL until the
10
+ # operation finishes and returns the final result as if the API call had
11
+ # been synchronous.
12
+ #
13
+ # @api private
14
+ module RespondAsync
15
+ HEADER_PREFER = "prefer"
16
+ HEADER_PREFERENCE_APPLIED = "preference-applied"
17
+ HEADER_LOCATION = "location"
18
+ RESPOND_ASYNC = "respond-async"
19
+
20
+ POLL_INTERVAL = 1.0
21
+ POLL_REQUEST_TIMEOUT = 60.0
22
+
23
+ # Timeout tracking for async polling.
24
+ #
25
+ # @api private
26
+ class Timeout
27
+ # @param timeout [Float]
28
+ def initialize(timeout)
29
+ @deadline = Turbopuffer::Internal::Util.monotonic_secs + timeout
30
+ end
31
+
32
+ # @return [Float]
33
+ def remaining
34
+ [@deadline - Turbopuffer::Internal::Util.monotonic_secs, 0].max
35
+ end
36
+
37
+ # @return [Float]
38
+ def poll_timeout
39
+ [remaining, POLL_REQUEST_TIMEOUT].min
40
+ end
41
+
42
+ # @return [Float]
43
+ def sleep_duration
44
+ [remaining, POLL_INTERVAL].min
45
+ end
46
+ end
47
+
48
+ class << self
49
+ # @param headers [Hash{String=>String}]
50
+ #
51
+ # @return [void]
52
+ def prepare_headers(headers)
53
+ headers[HEADER_PREFER] ||= RESPOND_ASYNC
54
+ end
55
+
56
+ # @param client [Turbopuffer::Internal::Transport::BaseClient]
57
+ # @param request [Hash{Symbol=>Object}] the original built request
58
+ # @param response [Net::HTTPResponse]
59
+ # @param stream [Enumerable<String>]
60
+ #
61
+ # @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
62
+ def maybe_poll(client, request, response, stream)
63
+ return [Integer(response.code), response, stream] unless respond_async_applied?(response)
64
+
65
+ # Drain the original 202 body so the connection returns to the pool.
66
+ stream&.each { next }
67
+
68
+ orig_url = request.fetch(:url)
69
+ location = extract_location(orig_url, response)
70
+
71
+ timeout = Timeout.new(request.fetch(:timeout))
72
+
73
+ loop do
74
+ result = poll_once(client, orig_url, location, timeout)
75
+ return result if result
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ # @param response [Net::HTTPResponse]
82
+ #
83
+ # @return [Boolean]
84
+ def respond_async_applied?(response)
85
+ return false unless response.code == "202"
86
+
87
+ applied = response[HEADER_PREFERENCE_APPLIED].to_s
88
+ applied.strip.downcase == RESPOND_ASYNC
89
+ end
90
+
91
+ # @param orig_url [URI::Generic]
92
+ # @param response [Net::HTTPResponse]
93
+ #
94
+ # @return [URI::Generic]
95
+ def extract_location(orig_url, response)
96
+ raw_location = response[HEADER_LOCATION].to_s.strip
97
+ if raw_location.empty?
98
+ raise Turbopuffer::Errors::APIError.new(
99
+ url: orig_url,
100
+ message: "Server returned async response without a 'Location' header."
101
+ )
102
+ end
103
+
104
+ # Normalize so the default port for the scheme is applied.
105
+ orig = URI(orig_url.to_s)
106
+
107
+ # Resolve the Location against the original request URL.
108
+ begin
109
+ location = URI.join(orig, raw_location)
110
+ rescue URI::InvalidURIError
111
+ raise Turbopuffer::Errors::APIError.new(
112
+ url: orig_url,
113
+ message: "malformed 'Location' header: #{raw_location.inspect}"
114
+ )
115
+ end
116
+
117
+ if [location.scheme, location.host, location.port] !=
118
+ [orig.scheme, orig.host, orig.port]
119
+ raise Turbopuffer::Errors::APIError.new(
120
+ url: orig_url,
121
+ message: "'Location' origin does not match request origin: #{raw_location.inspect}"
122
+ )
123
+ end
124
+
125
+ location
126
+ end
127
+
128
+ # @param client [Turbopuffer::Internal::Transport::BaseClient]
129
+ # @param orig_url [URI::Generic]
130
+ # @param location [URI::Generic]
131
+ # @param timeout [Timeout]
132
+ #
133
+ # @return [Array(Integer, Net::HTTPResponse, Array<String>), nil]
134
+ def poll_once(client, orig_url, location, timeout)
135
+ raise Turbopuffer::Errors::APITimeoutError.new(url: orig_url) if timeout.remaining.zero?
136
+
137
+ body =
138
+ begin
139
+ client.request(
140
+ method: :get,
141
+ path: location.request_uri,
142
+ model: Turbopuffer::Internal::Type::Unknown,
143
+ options: {
144
+ extra_headers: {HEADER_PREFER => ""},
145
+ timeout: timeout.poll_timeout
146
+ }
147
+ )
148
+ rescue JSON::ParserError => e
149
+ raise Turbopuffer::Errors::APIError.new(
150
+ url: orig_url,
151
+ message: "malformed poll response: #{e.message}"
152
+ )
153
+ end
154
+
155
+ case body
156
+ in {status: "running"}
157
+ sleep(timeout.sleep_duration)
158
+ nil
159
+ in {status: "finished", result: {success: success}}
160
+ response = Net::HTTPOK.new("1.1", 200, "OK")
161
+ response["content-type"] = "application/json"
162
+ [200, response, [JSON.generate(success)]]
163
+ in {status: "finished", result: {error: {status_code: Integer => err_status, **rest}}}
164
+ raise Turbopuffer::Errors::APIStatusError.for(
165
+ url: orig_url,
166
+ status: err_status,
167
+ headers: nil,
168
+ body: rest[:detail],
169
+ request: nil,
170
+ response: nil
171
+ )
172
+ else
173
+ raise Turbopuffer::Errors::APIError.new(
174
+ url: orig_url,
175
+ message: "malformed poll response: #{body.inspect}"
176
+ )
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -309,6 +309,8 @@ module Turbopuffer
309
309
  headers["x-stainless-timeout"] = timeout.to_s
310
310
  end
311
311
 
312
+ Turbopuffer::Internal::RespondAsync.prepare_headers(headers)
313
+
312
314
  headers.reject! { |_, v| v.to_s.empty? }
313
315
 
314
316
  body =
@@ -319,7 +321,10 @@ module Turbopuffer
319
321
  Turbopuffer::Internal::Util.deep_merge(*[req[:body], opts[:extra_body]].compact)
320
322
  end
321
323
 
322
- headers.delete("content-type") if body.nil?
324
+ # Generated methods always pass `req[:body]` for operations that define a
325
+ # request body, so only elide the content-type header when the operation
326
+ # has no body at all, not when an optional body param was omitted.
327
+ headers.delete("content-type") if body.nil? && !req.key?(:body)
323
328
 
324
329
  url = Turbopuffer::Internal::Util.join_parsed_uri(
325
330
  @base_url_components,
@@ -501,12 +506,18 @@ module Turbopuffer
501
506
 
502
507
  # Don't send the current retry count in the headers if the caller modified the header defaults.
503
508
  send_retry_header = request.fetch(:headers)["x-stainless-retry-count"] == "0"
504
- status, response, stream = send_request(
509
+ _, response, stream = send_request(
505
510
  request,
506
511
  redirect_count: 0,
507
512
  retry_count: 0,
508
513
  send_retry_header: send_retry_header
509
514
  )
515
+ status, response, stream = Turbopuffer::Internal::RespondAsync.maybe_poll(
516
+ self,
517
+ request,
518
+ response,
519
+ stream
520
+ )
510
521
 
511
522
  headers = Turbopuffer::Internal::Util.normalized_headers(response.each_header.to_h)
512
523
  decoded = Turbopuffer::Internal::Util.decode_content(headers, stream: stream)
@@ -11,13 +11,22 @@ module Turbopuffer
11
11
  required :max_edit_distance,
12
12
  -> { Turbopuffer::Internal::Type::ArrayOf[Turbopuffer::FuzzyMaxEditDistance] }
13
13
 
14
- # @!method initialize(max_edit_distance:)
14
+ # @!attribute case_sensitive
15
+ # Whether searching with Fuzzy filter is case-sensitive. Defaults to `true` (i.e.
16
+ # case-sensitive).
17
+ #
18
+ # @return [Boolean, nil]
19
+ optional :case_sensitive, Turbopuffer::Internal::Type::Boolean
20
+
21
+ # @!method initialize(max_edit_distance:, case_sensitive: nil)
15
22
  # Some parameter documentations has been truncated, see
16
23
  # {Turbopuffer::Models::FuzzyParams} for more details.
17
24
  #
18
25
  # Additional parameters for the Fuzzy filter.
19
26
  #
20
27
  # @param max_edit_distance [Array<Turbopuffer::Models::FuzzyMaxEditDistance>] Maximum edit distance allowed at each query length. Queries shorter than the fir
28
+ #
29
+ # @param case_sensitive [Boolean] Whether searching with Fuzzy filter is case-sensitive. Defaults to `true` (i.e.
21
30
  end
22
31
  end
23
32
  end
@@ -18,6 +18,12 @@ module Turbopuffer
18
18
  # @return [String]
19
19
  required :source_namespace, String
20
20
 
21
+ # @!attribute dest_encryption
22
+ # (Optional) The encryption configuration for the destination namespace.
23
+ #
24
+ # @return [Turbopuffer::Models::Encryption::CustomerManaged, Turbopuffer::Models::Encryption::Default, nil]
25
+ optional :dest_encryption, union: -> { Turbopuffer::Encryption }
26
+
21
27
  # @!attribute source_api_key
22
28
  # (Optional) An API key for the organization containing the source namespace
23
29
  #
@@ -30,11 +36,13 @@ module Turbopuffer
30
36
  # @return [String, nil]
31
37
  optional :source_region, String
32
38
 
33
- # @!method initialize(source_namespace:, namespace: nil, source_api_key: nil, source_region: nil, request_options: {})
39
+ # @!method initialize(source_namespace:, namespace: nil, dest_encryption: nil, source_api_key: nil, source_region: nil, request_options: {})
34
40
  # @param source_namespace [String] The namespace to copy documents from.
35
41
  #
36
42
  # @param namespace [String]
37
43
  #
44
+ # @param dest_encryption [Turbopuffer::Models::Encryption::CustomerManaged, Turbopuffer::Models::Encryption::Default] (Optional) The encryption configuration for the destination namespace.
45
+ #
38
46
  # @param source_api_key [String] (Optional) An API key for the organization containing the source namespace
39
47
  #
40
48
  # @param source_region [String] (Optional) The region of the source namespace.
@@ -36,12 +36,14 @@ module Turbopuffer
36
36
  #
37
37
  # Copy all documents from another namespace into this one.
38
38
  #
39
- # @overload copy_from(source_namespace:, namespace: nil, source_api_key: nil, source_region: nil, request_options: {})
39
+ # @overload copy_from(source_namespace:, namespace: nil, dest_encryption: nil, source_api_key: nil, source_region: nil, request_options: {})
40
40
  #
41
41
  # @param source_namespace [String] Body param: The namespace to copy documents from.
42
42
  #
43
43
  # @param namespace [String] Path param: The name of the namespace.
44
44
  #
45
+ # @param dest_encryption [Turbopuffer::Models::Encryption::CustomerManaged, Turbopuffer::Models::Encryption::Default] Body param: (Optional) The encryption configuration for the destination namespac
46
+ #
45
47
  # @param source_api_key [String] Body param: (Optional) An API key for the organization containing the source nam
46
48
  #
47
49
  # @param source_region [String] Body param: (Optional) The region of the source namespace.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Turbopuffer
4
- VERSION = "2.1.0"
4
+ VERSION = "2.3.0"
5
5
  end
data/lib/turbopuffer.rb CHANGED
@@ -51,6 +51,7 @@ require_relative "turbopuffer/file_part"
51
51
  require_relative "turbopuffer/errors"
52
52
  require_relative "turbopuffer/internal/transport/base_client"
53
53
  require_relative "turbopuffer/internal/transport/pooled_net_requester"
54
+ require_relative "turbopuffer/internal/respond_async"
54
55
  require_relative "turbopuffer/client"
55
56
  require_relative "turbopuffer/internal/namespace_page"
56
57
  require_relative "turbopuffer/models/pinning_config"
@@ -13,22 +13,38 @@ module Turbopuffer
13
13
  sig { returns(T::Array[Turbopuffer::FuzzyMaxEditDistance]) }
14
14
  attr_accessor :max_edit_distance
15
15
 
16
+ # Whether searching with Fuzzy filter is case-sensitive. Defaults to `true` (i.e.
17
+ # case-sensitive).
18
+ sig { returns(T.nilable(T::Boolean)) }
19
+ attr_reader :case_sensitive
20
+
21
+ sig { params(case_sensitive: T::Boolean).void }
22
+ attr_writer :case_sensitive
23
+
16
24
  # Additional parameters for the Fuzzy filter.
17
25
  sig do
18
26
  params(
19
- max_edit_distance: T::Array[Turbopuffer::FuzzyMaxEditDistance::OrHash]
27
+ max_edit_distance:
28
+ T::Array[Turbopuffer::FuzzyMaxEditDistance::OrHash],
29
+ case_sensitive: T::Boolean
20
30
  ).returns(T.attached_class)
21
31
  end
22
32
  def self.new(
23
33
  # Maximum edit distance allowed at each query length. Queries shorter than the
24
34
  # first threshold return no matches.
25
- max_edit_distance:
35
+ max_edit_distance:,
36
+ # Whether searching with Fuzzy filter is case-sensitive. Defaults to `true` (i.e.
37
+ # case-sensitive).
38
+ case_sensitive: nil
26
39
  )
27
40
  end
28
41
 
29
42
  sig do
30
43
  override.returns(
31
- { max_edit_distance: T::Array[Turbopuffer::FuzzyMaxEditDistance] }
44
+ {
45
+ max_edit_distance: T::Array[Turbopuffer::FuzzyMaxEditDistance],
46
+ case_sensitive: T::Boolean
47
+ }
32
48
  )
33
49
  end
34
50
  def to_hash
@@ -24,6 +24,30 @@ module Turbopuffer
24
24
  sig { returns(String) }
25
25
  attr_accessor :source_namespace
26
26
 
27
+ # (Optional) The encryption configuration for the destination namespace.
28
+ sig do
29
+ returns(
30
+ T.nilable(
31
+ T.any(
32
+ Turbopuffer::Encryption::CustomerManaged,
33
+ Turbopuffer::Encryption::Default
34
+ )
35
+ )
36
+ )
37
+ end
38
+ attr_reader :dest_encryption
39
+
40
+ sig do
41
+ params(
42
+ dest_encryption:
43
+ T.any(
44
+ Turbopuffer::Encryption::CustomerManaged::OrHash,
45
+ Turbopuffer::Encryption::Default::OrHash
46
+ )
47
+ ).void
48
+ end
49
+ attr_writer :dest_encryption
50
+
27
51
  # (Optional) An API key for the organization containing the source namespace
28
52
  sig { returns(T.nilable(String)) }
29
53
  attr_reader :source_api_key
@@ -42,6 +66,11 @@ module Turbopuffer
42
66
  params(
43
67
  source_namespace: String,
44
68
  namespace: String,
69
+ dest_encryption:
70
+ T.any(
71
+ Turbopuffer::Encryption::CustomerManaged::OrHash,
72
+ Turbopuffer::Encryption::Default::OrHash
73
+ ),
45
74
  source_api_key: String,
46
75
  source_region: String,
47
76
  request_options: Turbopuffer::RequestOptions::OrHash
@@ -51,6 +80,8 @@ module Turbopuffer
51
80
  # The namespace to copy documents from.
52
81
  source_namespace:,
53
82
  namespace: nil,
83
+ # (Optional) The encryption configuration for the destination namespace.
84
+ dest_encryption: nil,
54
85
  # (Optional) An API key for the organization containing the source namespace
55
86
  source_api_key: nil,
56
87
  # (Optional) The region of the source namespace.
@@ -64,6 +95,11 @@ module Turbopuffer
64
95
  {
65
96
  namespace: String,
66
97
  source_namespace: String,
98
+ dest_encryption:
99
+ T.any(
100
+ Turbopuffer::Encryption::CustomerManaged,
101
+ Turbopuffer::Encryption::Default
102
+ ),
67
103
  source_api_key: String,
68
104
  source_region: String,
69
105
  request_options: Turbopuffer::RequestOptions
@@ -25,6 +25,11 @@ module Turbopuffer
25
25
  params(
26
26
  source_namespace: String,
27
27
  namespace: String,
28
+ dest_encryption:
29
+ T.any(
30
+ Turbopuffer::Encryption::CustomerManaged::OrHash,
31
+ Turbopuffer::Encryption::Default::OrHash
32
+ ),
28
33
  source_api_key: String,
29
34
  source_region: String,
30
35
  request_options: Turbopuffer::RequestOptions::OrHash
@@ -35,6 +40,9 @@ module Turbopuffer
35
40
  source_namespace:,
36
41
  # Path param: The name of the namespace.
37
42
  namespace: nil,
43
+ # Body param: (Optional) The encryption configuration for the destination
44
+ # namespace.
45
+ dest_encryption: nil,
38
46
  # Body param: (Optional) An API key for the organization containing the source
39
47
  # namespace
40
48
  source_api_key: nil,
@@ -1,17 +1,26 @@
1
1
  module Turbopuffer
2
2
  module Models
3
3
  type fuzzy_params =
4
- { max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance] }
4
+ {
5
+ max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance],
6
+ case_sensitive: bool
7
+ }
5
8
 
6
9
  class FuzzyParams < Turbopuffer::Internal::Type::BaseModel
7
10
  attr_accessor max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance]
8
11
 
12
+ attr_reader case_sensitive: bool?
13
+
14
+ def case_sensitive=: (bool) -> bool
15
+
9
16
  def initialize: (
10
- max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance]
17
+ max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance],
18
+ ?case_sensitive: bool
11
19
  ) -> void
12
20
 
13
21
  def to_hash: -> {
14
- max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance]
22
+ max_edit_distance: ::Array[Turbopuffer::FuzzyMaxEditDistance],
23
+ case_sensitive: bool
15
24
  }
16
25
  end
17
26
  end
@@ -4,6 +4,7 @@ module Turbopuffer
4
4
  {
5
5
  namespace: String,
6
6
  source_namespace: String,
7
+ dest_encryption: Turbopuffer::Models::encryption,
7
8
  source_api_key: String,
8
9
  source_region: String
9
10
  }
@@ -19,6 +20,12 @@ module Turbopuffer
19
20
 
20
21
  attr_accessor source_namespace: String
21
22
 
23
+ attr_reader dest_encryption: Turbopuffer::Models::encryption?
24
+
25
+ def dest_encryption=: (
26
+ Turbopuffer::Models::encryption
27
+ ) -> Turbopuffer::Models::encryption
28
+
22
29
  attr_reader source_api_key: String?
23
30
 
24
31
  def source_api_key=: (String) -> String
@@ -30,6 +37,7 @@ module Turbopuffer
30
37
  def initialize: (
31
38
  source_namespace: String,
32
39
  ?namespace: String,
40
+ ?dest_encryption: Turbopuffer::Models::encryption,
33
41
  ?source_api_key: String,
34
42
  ?source_region: String,
35
43
  ?request_options: Turbopuffer::request_opts
@@ -38,6 +46,7 @@ module Turbopuffer
38
46
  def to_hash: -> {
39
47
  namespace: String,
40
48
  source_namespace: String,
49
+ dest_encryption: Turbopuffer::Models::encryption,
41
50
  source_api_key: String,
42
51
  source_region: String,
43
52
  request_options: Turbopuffer::RequestOptions
@@ -10,6 +10,7 @@ module Turbopuffer
10
10
  def copy_from: (
11
11
  source_namespace: String,
12
12
  ?namespace: String,
13
+ ?dest_encryption: Turbopuffer::Models::encryption,
13
14
  ?source_api_key: String,
14
15
  ?source_region: String,
15
16
  ?request_options: Turbopuffer::request_opts
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbopuffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Turbopuffer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-03 00:00:00.000000000 Z
11
+ date: 2026-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cgi
@@ -55,6 +55,7 @@ files:
55
55
  - lib/turbopuffer/file_part.rb
56
56
  - lib/turbopuffer/internal.rb
57
57
  - lib/turbopuffer/internal/namespace_page.rb
58
+ - lib/turbopuffer/internal/respond_async.rb
58
59
  - lib/turbopuffer/internal/transport/base_client.rb
59
60
  - lib/turbopuffer/internal/transport/pooled_net_requester.rb
60
61
  - lib/turbopuffer/internal/type/array_of.rb