bitfab 0.33.3 → 0.33.5

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: 44ebaac53c01dd84f179de5559eb3f00836c6c1a51f15520b8f10085bcfd6021
4
- data.tar.gz: b7255113aef3706aefd3a1017520f24e6127503418965a0db23e70573fdd3d0e
3
+ metadata.gz: 40eaaf83e783c54b0a0b373b681d82e1d96b01f4e99a424f68af1fffcd82a79e
4
+ data.tar.gz: ed01d854b7ed2ee101a6bab9d659bd977c7f5ee6f0cbd0b481675d76dba449ec
5
5
  SHA512:
6
- metadata.gz: de1b1c86dc8660477b87632d766e6f8fdf858d682248c9bd53d024fb3b423acc18d02d877ff567344e5a80aa686d0ad3e72bb02e8cc7dd099612e28ccdc02ad2
7
- data.tar.gz: bb0ea7013f448acffa4644a359c0c38198ce9c74caf2b77c3d4d4c80a3f5b6f6f0bd73591ffd653b97c99af6518bc0c12460d69ac65314faf5d047541d731d1c
6
+ metadata.gz: 8965c0c940f603355b3ddb75c9a93fc33e56d839a730bcbe750f2eee6db558cb4fcc2de79e9551ce5431737c8907284a7593abaa63935c84d49268b2a7eb1ed2
7
+ data.tar.gz: 6c8883368d7b7bc68c823cd73860722a6460543484c2a5b687b4beec7b26f8737f46d935a33fdaf9b5760fc413ba04f6313426e67b4cc624429840ec0d9d12f7
data/lib/bitfab/client.rb CHANGED
@@ -243,12 +243,23 @@ module Bitfab
243
243
  # Execute a block inside a span context, sending trace data on completion.
244
244
  # Called by Traceable, not intended for direct use.
245
245
  def execute_span(trace_function_key:, span_name:, span_type:, function_name:, args:, kwargs:,
246
- mock_on_replay: false)
246
+ capture_when: "always", mock_on_replay: false)
247
247
  # Decide at CALL time, not construction. The key may be set after the
248
248
  # client is built (env loaded later), so re-checking per call lets a
249
249
  # late-resolved key take effect.
250
250
  return yield unless tracing_enabled?
251
251
 
252
+ resolved_capture_when = capture_when.to_s
253
+ unless %w[always nested].include?(resolved_capture_when)
254
+ Bitfab.warn_once(
255
+ "invalid-capture-when:#{trace_function_key}",
256
+ "unknown capture_when value #{capture_when.inspect}; defaulting to \"always\". " \
257
+ "Valid values: \"always\", \"nested\"."
258
+ )
259
+ resolved_capture_when = "always"
260
+ end
261
+ return yield if resolved_capture_when == "nested" && SpanContext.current.nil?
262
+
252
263
  # Span setup runs before the user's block. Tracing is a side-channel, so
253
264
  # if anything here raises (id generation, trace-state bookkeeping, a
254
265
  # malformed replay mock tree) the user's method must still run. On failure
@@ -892,12 +903,15 @@ module Bitfab
892
903
  # @param method_name [Symbol] the method to wrap
893
904
  # @param name [String, nil] explicit span name (defaults to method name)
894
905
  # @param type [String] span type
906
+ # @param capture_when [String, Symbol] "always" to allow a root trace, or
907
+ # "nested" to capture only when another Bitfab span is active. Unknown
908
+ # values warn once and default to "always"
895
909
  # @param mock_on_replay [Boolean] mark this span for the default "marked" mock strategy
896
- def wrap(klass, method_name, name: nil, type: "custom", mock_on_replay: false)
910
+ def wrap(klass, method_name, name: nil, type: "custom", capture_when: "always", mock_on_replay: false)
897
911
  Bitfab::Traceable.wrap(
898
912
  klass, method_name,
899
913
  trace_function_key: @trace_function_key,
900
- name:, type:, mock_on_replay:,
914
+ name:, type:, capture_when:, mock_on_replay:,
901
915
  client: @client
902
916
  )
903
917
  end
data/lib/bitfab/replay.rb CHANGED
@@ -127,10 +127,10 @@ module Bitfab
127
127
  # source_trace_id/source_span_id aliases), and returns [new_args, new_kwargs].
128
128
  # Runs per item inside the same rescue as the method, so a raising adapter
129
129
  # sets that item's :error rather than crashing the run.
130
- # @param db_branch [Hash, nil] passing it at all turns database branching
131
- # on, so +{}+ enables it with the mirror project's own sizing. Keys
132
- # +:min_cu+/+:max_cu+ are the branch compute's autoscaling floor and
133
- # ceiling in Neon Compute Units, and +:warmup_sql+ warms the branch's
130
+ # @param db_branch [Boolean, Hash, nil] +true+ branches with the mirror
131
+ # project's own sizing; a Hash tunes it and +false+/+nil+ leave branching
132
+ # off. Keys +:min_cu+/+:max_cu+ are the branch compute's autoscaling floor
133
+ # and ceiling in Neon Compute Units, and +:warmup_sql+ warms the branch's
134
134
  # cache before the replayed method sees it. Read the resolved branch
135
135
  # inside the method with +Bitfab.current_replay_branch+.
136
136
  # @param on_progress [#call, nil] optional callback invoked once per item as
@@ -192,7 +192,7 @@ module Bitfab
192
192
  # the count), so it's omitted from the request entirely.
193
193
  effective_limit = trace_ids ? nil : (limit || 5)
194
194
 
195
- include_db_branch_lease = !db_branch.nil?
195
+ include_db_branch_lease = db_branch_enabled?(db_branch)
196
196
 
197
197
  # code_change_files controls capture: omitted auto-captures, an array
198
198
  # wins, and explicit nil opts out. Preserve a caller-supplied description
@@ -335,16 +335,26 @@ module Bitfab
335
335
  CC_MAX_FILE_BYTES = 500_000
336
336
  CC_MAX_TOTAL_BYTES = 2_000_000
337
337
 
338
+ # Whether the caller asked for database branching. +true+ and a Hash both
339
+ # turn it on; +false+ and +nil+ leave it off. Kept separate from
340
+ # +db_branch_settings+ because +db_branch: true+ enables branching while
341
+ # contributing no settings, so the presence of settings can't stand in for
342
+ # the switch.
343
+ def db_branch_enabled?(db_branch)
344
+ !db_branch.nil? && db_branch != false
345
+ end
346
+
338
347
  # Convert the caller's +db_branch+ options to the wire shape, or nil when
339
348
  # nothing was set. Dropping the key entirely keeps the request identical to
340
- # what older SDKs send.
349
+ # what older SDKs send. Booleans carry no settings: they only move the
350
+ # switch.
341
351
  #
342
352
  # Keys: :min_cu and :max_cu are the branch compute's autoscaling floor and
343
353
  # ceiling in Neon Compute Units (equal values pin the size, keeping items
344
354
  # comparable); :warmup_sql is appended to the branch's readiness check so it
345
355
  # warms the cache before the replayed function sees the lease.
346
356
  def db_branch_settings(db_branch)
347
- return nil if db_branch.nil? || db_branch.empty?
357
+ return nil if db_branch.nil? || db_branch == true || db_branch == false || db_branch.empty?
348
358
 
349
359
  # Symbol or string keys, matching normalize_code_change_files: a hash
350
360
  # assembled from JSON or YAML would otherwise be read as empty, leaving
@@ -38,6 +38,9 @@ module Bitfab
38
38
  # @param trace_function_key [String] the trace function key
39
39
  # @param name [String, nil] explicit span name (defaults to method name)
40
40
  # @param type [String] span type: llm, agent, function, guardrail, handoff, custom
41
+ # @param capture_when [String, Symbol] "always" to allow a root trace, or
42
+ # "nested" to capture only when another Bitfab span is active. Unknown
43
+ # values warn once and default to "always"
41
44
  # @param mock_on_replay [Boolean] mark this span for the default "marked" mock strategy.
42
45
  # When true, `client.replay(...)` returns this span's
43
46
  # historical output instead of executing the wrapped method.
@@ -48,7 +51,7 @@ module Bitfab
48
51
  # preserve the bound client through the fluent wrapper, matching Python's
49
52
  # `BitfabFunction.span()` and TypeScript's `BitfabFunction.withSpan()`.
50
53
  def self.wrap(klass, method_name, trace_function_key:, name: nil, type: "custom",
51
- mock_on_replay: false, client: nil)
54
+ capture_when: "always", mock_on_replay: false, client: nil)
52
55
  span_name = name || method_name.to_s
53
56
  method_name_str = method_name.to_s
54
57
  bound_client = client
@@ -63,6 +66,7 @@ module Bitfab
63
66
  function_name: method_name_str,
64
67
  args:,
65
68
  kwargs:,
69
+ capture_when:,
66
70
  mock_on_replay:) do
67
71
  super(*args, **kwargs, &block)
68
72
  end
@@ -132,10 +136,14 @@ module Bitfab
132
136
  # @param trace_function_key [String, nil] trace function key (overrides class-level bitfab_function)
133
137
  # @param name [String, nil] explicit span name (defaults to method name)
134
138
  # @param type [String] span type: llm, agent, function, guardrail, handoff, custom
139
+ # @param capture_when [String, Symbol] "always" to allow a root trace, or
140
+ # "nested" to capture only when another Bitfab span is active. Unknown
141
+ # values warn once and default to "always"
135
142
  # @param mock_on_replay [Boolean] mark this span for the default "marked" mock strategy.
136
143
  # When true, `client.replay(...)` returns this span's
137
144
  # historical output instead of executing the wrapped method.
138
- def bitfab_span(method_name, trace_function_key: nil, name: nil, type: "custom", mock_on_replay: false)
145
+ def bitfab_span(method_name, trace_function_key: nil, name: nil, type: "custom",
146
+ capture_when: "always", mock_on_replay: false)
139
147
  trace_function_key ||= @bitfab_function_key
140
148
  unless trace_function_key
141
149
  raise "No trace function key provided. Pass `trace_function_key:` to `bitfab_span` " \
@@ -144,7 +152,9 @@ module Bitfab
144
152
 
145
153
  # If the method already exists (inline or after-method style), wrap it immediately
146
154
  if method_defined?(method_name) || private_method_defined?(method_name)
147
- _bitfab_wrap_method(method_name, trace_function_key:, name:, type:, mock_on_replay:)
155
+ _bitfab_wrap_method(
156
+ method_name, trace_function_key:, name:, type:, capture_when:, mock_on_replay:
157
+ )
148
158
  else
149
159
  # Method doesn't exist yet (before-method style) - register for method_added hook
150
160
  @_bitfab_pending_spans ||= {}
@@ -152,6 +162,7 @@ module Bitfab
152
162
  trace_function_key:,
153
163
  name:,
154
164
  type:,
165
+ capture_when:,
155
166
  mock_on_replay:
156
167
  }
157
168
  end
@@ -167,7 +178,8 @@ module Bitfab
167
178
  _bitfab_wrap_method(method_name, **config)
168
179
  end
169
180
 
170
- def _bitfab_wrap_method(method_name, trace_function_key:, name: nil, type: "custom", mock_on_replay: false)
181
+ def _bitfab_wrap_method(method_name, trace_function_key:, name: nil, type: "custom",
182
+ capture_when: "always", mock_on_replay: false)
171
183
  span_name = name || method_name.to_s
172
184
  method_name_str = method_name.to_s
173
185
 
@@ -185,6 +197,7 @@ module Bitfab
185
197
  function_name: method_name_str,
186
198
  args:,
187
199
  kwargs:,
200
+ capture_when:,
188
201
  mock_on_replay:) do
189
202
  super(*args, **kwargs, &block)
190
203
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.33.3"
4
+ VERSION = "0.33.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitfab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.33.3
4
+ version: 0.33.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team