bitfab 0.33.2 → 0.33.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/lib/bitfab/client.rb +25 -6
- data/lib/bitfab/replay.rb +17 -10
- data/lib/bitfab/traceable.rb +17 -4
- data/lib/bitfab/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 12cae09488f9200115e768e31661e55be850acc2dbcf2b53eece9c4ab4d59ca2
|
|
4
|
+
data.tar.gz: 3242cb27cbd71d15094bc4024cb914a494eefa2eeee317e1d45c8ba77c77f4a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 11f4111de6c94527b2f4b14757b50ccaddea211d3366bf1a5241e8e7e0ffa065138a84fa7f6db84baaec926cfeb9754fe7024a090b297ecb35e7916a1fc517f1
|
|
7
|
+
data.tar.gz: 880b440e2610064045ff1e753d65167c46be2a7220897aa0631b739e24affec2e99cd05de12acf2d39f162474d8fbec6ff13b614f60c6390529395ad2478e4ab
|
data/lib/bitfab/client.rb
CHANGED
|
@@ -76,9 +76,14 @@ module Bitfab
|
|
|
76
76
|
# @param trace_ids [Array<String>, nil] optional list of trace IDs to replay (max 100)
|
|
77
77
|
# @param max_concurrency [Integer, nil] max threads for parallel replay (default: 10)
|
|
78
78
|
# @param code_change_description [String, nil] optional rationale for the
|
|
79
|
-
# code change being tested in this replay (stored on the experiment)
|
|
79
|
+
# code change being tested in this replay (stored on the experiment).
|
|
80
|
+
# When supplied without code_change_files, this text is preserved while
|
|
81
|
+
# the SDK automatically captures the files.
|
|
82
|
+
# Pass nil when the replay should have no description; use
|
|
83
|
+
# code_change_files: nil to suppress automatic file capture.
|
|
80
84
|
# @param code_change_files [Array<Hash>, nil] optional list of edited files,
|
|
81
|
-
# each as { path:, before:, after: } (use "" for new/deleted files)
|
|
85
|
+
# each as { path:, before:, after: } (use "" for new/deleted files).
|
|
86
|
+
# Omit to capture automatically, or pass nil to suppress file capture.
|
|
82
87
|
# @param experiment_group_id [String, nil] optional UUID grouping multiple
|
|
83
88
|
# replay runs into a single experiment batch
|
|
84
89
|
# @param dataset_id [String, nil] optional UUID of the dataset this replay
|
|
@@ -118,7 +123,7 @@ module Bitfab
|
|
|
118
123
|
# A raising callback never crashes the run.
|
|
119
124
|
# @return [Hash] with :items, :test_run_id, :test_run_url
|
|
120
125
|
def replay(receiver, method_name, trace_function_key:, limit: nil, trace_ids: nil, max_concurrency: 10,
|
|
121
|
-
name: nil, code_change_description:
|
|
126
|
+
name: nil, code_change_description: Replay::CODE_CHANGE_UNSET, code_change_files: Replay::CODE_CHANGE_UNSET, experiment_group_id: nil, dataset_id: nil, grader_ids: nil, mock: "marked",
|
|
122
127
|
adapt_inputs: nil, mock_override: nil, db_branch: nil, on_progress: nil)
|
|
123
128
|
Replay.run(
|
|
124
129
|
self, receiver, method_name,
|
|
@@ -238,12 +243,23 @@ module Bitfab
|
|
|
238
243
|
# Execute a block inside a span context, sending trace data on completion.
|
|
239
244
|
# Called by Traceable, not intended for direct use.
|
|
240
245
|
def execute_span(trace_function_key:, span_name:, span_type:, function_name:, args:, kwargs:,
|
|
241
|
-
mock_on_replay: false)
|
|
246
|
+
capture_when: "always", mock_on_replay: false)
|
|
242
247
|
# Decide at CALL time, not construction. The key may be set after the
|
|
243
248
|
# client is built (env loaded later), so re-checking per call lets a
|
|
244
249
|
# late-resolved key take effect.
|
|
245
250
|
return yield unless tracing_enabled?
|
|
246
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
|
+
|
|
247
263
|
# Span setup runs before the user's block. Tracing is a side-channel, so
|
|
248
264
|
# if anything here raises (id generation, trace-state bookkeeping, a
|
|
249
265
|
# malformed replay mock tree) the user's method must still run. On failure
|
|
@@ -887,12 +903,15 @@ module Bitfab
|
|
|
887
903
|
# @param method_name [Symbol] the method to wrap
|
|
888
904
|
# @param name [String, nil] explicit span name (defaults to method name)
|
|
889
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"
|
|
890
909
|
# @param mock_on_replay [Boolean] mark this span for the default "marked" mock strategy
|
|
891
|
-
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)
|
|
892
911
|
Bitfab::Traceable.wrap(
|
|
893
912
|
klass, method_name,
|
|
894
913
|
trace_function_key: @trace_function_key,
|
|
895
|
-
name:, type:, mock_on_replay:,
|
|
914
|
+
name:, type:, capture_when:, mock_on_replay:,
|
|
896
915
|
client: @client
|
|
897
916
|
)
|
|
898
917
|
end
|
data/lib/bitfab/replay.rb
CHANGED
|
@@ -81,6 +81,8 @@ module Bitfab
|
|
|
81
81
|
|
|
82
82
|
# Replay historical traces through a traced method and create a test run.
|
|
83
83
|
module Replay
|
|
84
|
+
CODE_CHANGE_UNSET = Object.new.freeze
|
|
85
|
+
|
|
84
86
|
module_function
|
|
85
87
|
|
|
86
88
|
# Replay historical traces through a method and create a test run.
|
|
@@ -99,9 +101,14 @@ module Bitfab
|
|
|
99
101
|
# @param name [String, nil] optional display name for the resulting experiment/test run
|
|
100
102
|
# @param max_concurrency [Integer, nil] max threads for parallel replay (default: 10)
|
|
101
103
|
# @param code_change_description [String, nil] optional rationale for the
|
|
102
|
-
# code change being tested in this replay (stored on the experiment)
|
|
104
|
+
# code change being tested in this replay (stored on the experiment).
|
|
105
|
+
# When supplied without code_change_files, this text is preserved while
|
|
106
|
+
# the SDK automatically captures the files.
|
|
107
|
+
# Pass nil when the replay should have no description; use
|
|
108
|
+
# code_change_files: nil to suppress automatic file capture.
|
|
103
109
|
# @param code_change_files [Array<Hash>, nil] optional list of edited files,
|
|
104
|
-
# each as { path:, before:, after: } (empty string for new/deleted files)
|
|
110
|
+
# each as { path:, before:, after: } (empty string for new/deleted files).
|
|
111
|
+
# Omit to capture automatically, or pass nil to suppress file capture.
|
|
105
112
|
# @param experiment_group_id [String, nil] optional UUID grouping multiple
|
|
106
113
|
# replay runs into a single experiment batch
|
|
107
114
|
# @param dataset_id [String, nil] optional UUID of the dataset this replay
|
|
@@ -140,7 +147,7 @@ module Bitfab
|
|
|
140
147
|
# crashes the run.
|
|
141
148
|
# @return [Hash] with :items, :test_run_id, :test_run_url
|
|
142
149
|
def run(client, receiver, method_name, trace_function_key:, limit: nil, trace_ids: nil, name: nil,
|
|
143
|
-
max_concurrency: 10, code_change_description:
|
|
150
|
+
max_concurrency: 10, code_change_description: CODE_CHANGE_UNSET, code_change_files: CODE_CHANGE_UNSET, experiment_group_id: nil,
|
|
144
151
|
dataset_id: nil, grader_ids: nil, mock: "marked",
|
|
145
152
|
adapt_inputs: nil, mock_override: nil, db_branch: nil, on_progress: nil)
|
|
146
153
|
unless MOCK_STRATEGIES.include?(mock.to_s)
|
|
@@ -187,18 +194,18 @@ module Bitfab
|
|
|
187
194
|
|
|
188
195
|
include_db_branch_lease = !db_branch.nil?
|
|
189
196
|
|
|
190
|
-
#
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
|
|
194
|
-
# assistant's make-change rails.
|
|
195
|
-
if code_change_description.nil? && code_change_files.nil?
|
|
197
|
+
# code_change_files controls capture: omitted auto-captures, an array
|
|
198
|
+
# wins, and explicit nil opts out. Preserve a caller-supplied description
|
|
199
|
+
# while filling only the omitted files.
|
|
200
|
+
if code_change_files.equal?(CODE_CHANGE_UNSET)
|
|
196
201
|
captured = resolve_auto_code_change(name)
|
|
197
202
|
unless captured.nil?
|
|
198
|
-
code_change_description = captured[0]
|
|
199
203
|
code_change_files = captured[1]
|
|
204
|
+
code_change_description = captured[0] if code_change_description.equal?(CODE_CHANGE_UNSET)
|
|
200
205
|
end
|
|
201
206
|
end
|
|
207
|
+
code_change_description = nil if code_change_description.equal?(CODE_CHANGE_UNSET)
|
|
208
|
+
code_change_files = nil if code_change_files.equal?(CODE_CHANGE_UNSET)
|
|
202
209
|
|
|
203
210
|
resolved_db_branch_settings = db_branch_settings(db_branch)
|
|
204
211
|
replay_data = http_client.start_replay(
|
data/lib/bitfab/traceable.rb
CHANGED
|
@@ -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",
|
|
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(
|
|
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",
|
|
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
|
data/lib/bitfab/version.rb
CHANGED