bitfab 0.73.1 → 0.74.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 +4 -4
- data/lib/bitfab/client.rb +8 -1
- data/lib/bitfab/http_client.rb +8 -1
- data/lib/bitfab/replay.rb +20 -1
- data/lib/bitfab/replay_registry.rb +32 -11
- data/lib/bitfab/scenarios.rb +8 -2
- 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: 3c5d6ffd1ec89aa3d5e4bd2cbb3a261d5e4007065c3481a4f33898255ab34d37
|
|
4
|
+
data.tar.gz: 0c662b87145b14ce88ab61aa62e28c8e473de63d42a8335c687df9586353fb44
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ff0a584aa0928967b16865aa5e107b895180cde0ea03fa4146f0bff1ebf0b53ba869310ce6c9658bec06583e35c11b897a5e996816f619389b1a8019c8f7909
|
|
7
|
+
data.tar.gz: d5d1783b9c5af65a670757dd445ea937b339a6faeadc42b564f78e143e392bc359f394bfbc586d613df9f3a20457f345f71e842bc89497fed8c9caba1eb20f08
|
data/lib/bitfab/client.rb
CHANGED
|
@@ -182,6 +182,12 @@ module Bitfab
|
|
|
182
182
|
# directly to this experiment, graded as the union with the dataset's
|
|
183
183
|
# runnable graders at completion; each must be an active/live grader in the
|
|
184
184
|
# same org and trace function or the server rejects the replay
|
|
185
|
+
# @param category_ids [Array<String>, nil] optional category UUIDs. With
|
|
186
|
+
# trace_ids, dataset_id or dataset_ids, only the selected traces carrying
|
|
187
|
+
# an approved assertion in one of these categories replay. It changes
|
|
188
|
+
# which traces replay, not which assertions are judged. Raises
|
|
189
|
+
# ArgumentError when empty or passed without a trace ID or dataset
|
|
190
|
+
# selection.
|
|
185
191
|
# @param mock [String] mock strategy for child spans: "marked" (default),
|
|
186
192
|
# "none", or "all". "marked" only mocks spans declared with
|
|
187
193
|
# mock_on_replay: true; "all" mocks every matched recorded child span. A selected
|
|
@@ -228,7 +234,7 @@ module Bitfab
|
|
|
228
234
|
# @return [Hash] with :items, :experiment_id, :experiment_url, and the
|
|
229
235
|
# deprecated aliases :test_run_id and :test_run_url carrying the same values
|
|
230
236
|
def replay(receiver, method_name = nil, trace_function_key:, limit: nil, trace_ids: nil, concurrency: nil, max_concurrency: ReplayConcurrency::UNSET,
|
|
231
|
-
name: nil, notes: nil, metadata: nil, code_change: nil, code_change_description: nil, code_change_files: nil, code_change_base: nil, experiment_group_id: nil, experiment_group_name: nil, dataset_id: nil, dataset_ids: nil, grader_ids: nil, mock: "marked", attempts: ReplayConcurrency::UNSET, only_with_assertions: false, skip_assertion_judging: false, judge_assertions: nil, dry_run: false,
|
|
237
|
+
name: nil, notes: nil, metadata: nil, code_change: nil, code_change_description: nil, code_change_files: nil, code_change_base: nil, experiment_group_id: nil, experiment_group_name: nil, dataset_id: nil, dataset_ids: nil, grader_ids: nil, mock: "marked", attempts: ReplayConcurrency::UNSET, only_with_assertions: false, category_ids: nil, skip_assertion_judging: false, judge_assertions: nil, dry_run: false,
|
|
232
238
|
adapt_inputs: nil, mock_override: nil, db_branch: nil, on_item_start: nil, on_item_finish: nil, on_progress: nil,
|
|
233
239
|
on_experiment_start: nil, experimental_selective_replay: nil)
|
|
234
240
|
Replay.run(
|
|
@@ -245,6 +251,7 @@ module Bitfab
|
|
|
245
251
|
max_concurrency:,
|
|
246
252
|
attempts:,
|
|
247
253
|
only_with_assertions:,
|
|
254
|
+
category_ids:,
|
|
248
255
|
skip_assertion_judging:,
|
|
249
256
|
judge_assertions:,
|
|
250
257
|
dry_run:,
|
data/lib/bitfab/http_client.rb
CHANGED
|
@@ -276,9 +276,15 @@ module Bitfab
|
|
|
276
276
|
# directly to this experiment, graded as the union with the dataset's
|
|
277
277
|
# runnable graders at completion; each must be an active/live grader in the
|
|
278
278
|
# same org and trace function or the server rejects the replay
|
|
279
|
+
# @param category_ids [Array<String>, nil] optional category UUIDs. With
|
|
280
|
+
# trace_ids, dataset_id or dataset_ids, only the selected traces carrying
|
|
281
|
+
# an approved assertion in one of these categories replay. It changes
|
|
282
|
+
# which traces replay, not which assertions are judged. Raises
|
|
283
|
+
# ArgumentError when empty or passed without a trace ID or dataset
|
|
284
|
+
# selection.
|
|
279
285
|
def start_replay(trace_function_key, limit, trace_ids: nil, code_change_type: nil, code_change_description: nil,
|
|
280
286
|
code_change_files: nil, experiment_group_id: nil, experiment_group_name: nil, name: nil, notes: nil, metadata: nil, include_db_branch_lease: false, dataset_ids: nil,
|
|
281
|
-
grader_ids: nil, db_branch_settings: nil, attempts: 1, only_with_assertions: false, skip_assertion_judging: false, include_original_metadata: false, experimental_selective_replay: nil, dry_run: false, invocation: nil)
|
|
287
|
+
grader_ids: nil, db_branch_settings: nil, attempts: 1, only_with_assertions: false, category_ids: nil, skip_assertion_judging: false, include_original_metadata: false, experimental_selective_replay: nil, dry_run: false, invocation: nil)
|
|
282
288
|
payload = {
|
|
283
289
|
"traceFunctionKey" => trace_function_key
|
|
284
290
|
}
|
|
@@ -306,6 +312,7 @@ module Bitfab
|
|
|
306
312
|
payload["graderIds"] = grader_ids unless grader_ids.nil?
|
|
307
313
|
payload["attempts"] = attempts if attempts > 1
|
|
308
314
|
payload["onlyWithAssertions"] = true if only_with_assertions
|
|
315
|
+
payload["categoryIds"] = category_ids unless category_ids.nil?
|
|
309
316
|
payload["judgeAssertions"] = true unless skip_assertion_judging
|
|
310
317
|
payload["dryRun"] = true if dry_run
|
|
311
318
|
payload["includeOriginalMetadata"] = true if include_original_metadata
|
data/lib/bitfab/replay.rb
CHANGED
|
@@ -274,6 +274,12 @@ module Bitfab
|
|
|
274
274
|
# directly to this experiment, graded as the union with the dataset's
|
|
275
275
|
# runnable graders at completion; each must be an active/live grader in the
|
|
276
276
|
# same org and trace function or the server rejects the replay
|
|
277
|
+
# @param category_ids [Array<String>, nil] optional category UUIDs. With
|
|
278
|
+
# trace_ids, dataset_id or dataset_ids, only the selected traces carrying
|
|
279
|
+
# an approved assertion in one of these categories replay. It changes
|
|
280
|
+
# which traces replay, not which assertions are judged. Raises
|
|
281
|
+
# ArgumentError when empty or passed without a trace ID or dataset
|
|
282
|
+
# selection.
|
|
277
283
|
# @param mock [String] mock strategy for child spans: "marked" (default),
|
|
278
284
|
# "none", or "all". "marked" only mocks spans declared with
|
|
279
285
|
# mock_on_replay: true; "all" mocks every matched recorded child span.
|
|
@@ -320,7 +326,7 @@ module Bitfab
|
|
|
320
326
|
# and progress events then carry a nil :experiment_id too.
|
|
321
327
|
def run(client, receiver, method_name, trace_function_key:, limit: nil, trace_ids: nil, name: nil, notes: nil, metadata: nil,
|
|
322
328
|
concurrency: nil, max_concurrency: ReplayConcurrency::UNSET, code_change: nil, code_change_description: nil, code_change_files: nil, code_change_base: nil, experiment_group_id: nil, experiment_group_name: nil,
|
|
323
|
-
dataset_id: nil, dataset_ids: nil, grader_ids: nil, mock: "marked", attempts: ReplayConcurrency::UNSET, only_with_assertions: false, skip_assertion_judging: false, judge_assertions: nil, dry_run: false,
|
|
329
|
+
dataset_id: nil, dataset_ids: nil, grader_ids: nil, mock: "marked", attempts: ReplayConcurrency::UNSET, only_with_assertions: false, category_ids: nil, skip_assertion_judging: false, judge_assertions: nil, dry_run: false,
|
|
324
330
|
adapt_inputs: nil, mock_override: nil, db_branch: nil, on_item_start: nil, on_item_finish: nil, on_progress: nil,
|
|
325
331
|
on_experiment_start: nil, experimental_selective_replay: nil)
|
|
326
332
|
validate_code_change(code_change, code_change_description, code_change_files, code_change_base)
|
|
@@ -355,6 +361,7 @@ module Bitfab
|
|
|
355
361
|
end
|
|
356
362
|
end
|
|
357
363
|
resolved_dataset_ids = resolve_dataset_ids(dataset_id, dataset_ids)
|
|
364
|
+
validate_category_ids(category_ids, trace_ids, resolved_dataset_ids)
|
|
358
365
|
if limit && trace_ids
|
|
359
366
|
warn "Bitfab: limit is ignored when trace_ids is passed: the explicit trace ID list already " \
|
|
360
367
|
"determines how many traces replay."
|
|
@@ -422,6 +429,7 @@ module Bitfab
|
|
|
422
429
|
grader_ids:,
|
|
423
430
|
attempts:,
|
|
424
431
|
only_with_assertions:,
|
|
432
|
+
category_ids:,
|
|
425
433
|
skip_assertion_judging:,
|
|
426
434
|
include_original_metadata: !adapt_inputs.nil?,
|
|
427
435
|
db_branch_settings: resolved_db_branch_settings,
|
|
@@ -613,6 +621,17 @@ module Bitfab
|
|
|
613
621
|
skip_assertion_judging || judge_assertions == false
|
|
614
622
|
end
|
|
615
623
|
|
|
624
|
+
def validate_category_ids(category_ids, trace_ids, dataset_ids)
|
|
625
|
+
return if category_ids.nil?
|
|
626
|
+
if category_ids.empty?
|
|
627
|
+
raise ArgumentError, "category_ids must contain at least one category ID."
|
|
628
|
+
end
|
|
629
|
+
return if trace_ids || dataset_ids
|
|
630
|
+
|
|
631
|
+
raise ArgumentError,
|
|
632
|
+
"category_ids narrows a trace ID or dataset selection. Pass it with trace_ids, dataset_id or dataset_ids."
|
|
633
|
+
end
|
|
634
|
+
|
|
616
635
|
def resolve_dataset_ids(dataset_id, dataset_ids)
|
|
617
636
|
if dataset_id && dataset_ids
|
|
618
637
|
raise ArgumentError,
|
|
@@ -20,7 +20,7 @@ module Bitfab
|
|
|
20
20
|
class ReplayRegistry
|
|
21
21
|
OPTION_NAMES = %i[
|
|
22
22
|
limit trace_ids name notes metadata concurrency max_concurrency experiment_group_id experiment_group_name dataset_id dataset_ids grader_ids mock
|
|
23
|
-
mock_override adapt_inputs db_branch attempts only_with_assertions skip_assertion_judging judge_assertions dry_run on_item_finish
|
|
23
|
+
mock_override adapt_inputs db_branch attempts only_with_assertions category_ids skip_assertion_judging judge_assertions dry_run on_item_finish
|
|
24
24
|
].freeze
|
|
25
25
|
|
|
26
26
|
def initialize
|
|
@@ -97,31 +97,39 @@ module Bitfab
|
|
|
97
97
|
# approved assertion is checked on a replay, so narrowing on anything else
|
|
98
98
|
# would pick traces the run cannot be judged against. The server applies the
|
|
99
99
|
# same rule when it revalidates the selection.
|
|
100
|
-
def approved_assertion?(assertions)
|
|
101
|
-
assertions.any?
|
|
100
|
+
def approved_assertion?(assertions, category_ids = nil)
|
|
101
|
+
assertions.any? do |assertion|
|
|
102
|
+
assertion["approvalState"] == "approved" &&
|
|
103
|
+
(category_ids.nil? || category_ids.include?(assertion["category_id"]))
|
|
104
|
+
end
|
|
102
105
|
end
|
|
103
106
|
|
|
104
|
-
def bound_trace_ids(client, trace_ids, limit, only_with_assertions)
|
|
107
|
+
def bound_trace_ids(client, trace_ids, limit, only_with_assertions, category_ids = nil)
|
|
105
108
|
unless limit.is_a?(Integer) && limit.positive?
|
|
106
109
|
raise ArgumentError, "Replay limit must be a positive integer."
|
|
107
110
|
end
|
|
108
|
-
|
|
111
|
+
narrows = only_with_assertions || !category_ids.nil?
|
|
112
|
+
return trace_ids.first(limit) if !narrows || limit >= trace_ids.length
|
|
109
113
|
|
|
110
114
|
selected = []
|
|
111
115
|
trace_ids.each do |trace_id|
|
|
112
116
|
result = client.traces.get_assertions(trace_id)
|
|
113
|
-
if result.fetch("inheritedFrom").nil? && approved_assertion?(result.fetch("assertions"))
|
|
117
|
+
if result.fetch("inheritedFrom").nil? && approved_assertion?(result.fetch("assertions"), category_ids)
|
|
114
118
|
selected << trace_id
|
|
115
119
|
break if selected.length == limit
|
|
116
120
|
end
|
|
117
121
|
end
|
|
118
122
|
if selected.empty?
|
|
123
|
+
if category_ids
|
|
124
|
+
raise ArgumentError,
|
|
125
|
+
"No traces with an approved assertion in the given categories matched this replay selection."
|
|
126
|
+
end
|
|
119
127
|
raise ArgumentError, "No traces with approved assertions matched this replay selection."
|
|
120
128
|
end
|
|
121
129
|
selected
|
|
122
130
|
end
|
|
123
131
|
|
|
124
|
-
def pinned_dataset_members(client, dataset_ids, limit, only_with_assertions = false)
|
|
132
|
+
def pinned_dataset_members(client, dataset_ids, limit, only_with_assertions = false, category_ids = nil)
|
|
125
133
|
members = dataset_ids.flat_map { |dataset_id|
|
|
126
134
|
client.datasets.list_traces(dataset_id).fetch("traceIds")
|
|
127
135
|
}.uniq.sort
|
|
@@ -134,7 +142,7 @@ module Bitfab
|
|
|
134
142
|
"every selected dataset in full."
|
|
135
143
|
end
|
|
136
144
|
|
|
137
|
-
bound_trace_ids(client, members, limit, only_with_assertions)
|
|
145
|
+
bound_trace_ids(client, members, limit, only_with_assertions, category_ids)
|
|
138
146
|
end
|
|
139
147
|
|
|
140
148
|
def run(registry, argv: ARGV, stdout: $stdout, stderr: $stderr)
|
|
@@ -173,24 +181,32 @@ module Bitfab
|
|
|
173
181
|
end
|
|
174
182
|
|
|
175
183
|
only_with_assertions = args[:only_with_assertions] || options[:only_with_assertions]
|
|
184
|
+
category_ids = args[:category_ids] || options[:category_ids]
|
|
176
185
|
bound = args[:limit] || options[:limit]
|
|
177
186
|
options.delete(:limit)
|
|
178
187
|
bounded_dataset_ids = args[:dataset_ids] || options[:dataset_ids]
|
|
179
188
|
|
|
189
|
+
if category_ids && options[:trace_ids].nil? && bounded_dataset_ids.nil?
|
|
190
|
+
raise ArgumentError,
|
|
191
|
+
"--category-ids narrows a trace ID or dataset selection. Pass it with --trace-ids or --dataset-ids."
|
|
192
|
+
end
|
|
193
|
+
|
|
180
194
|
if options[:trace_ids]
|
|
181
195
|
if bound
|
|
182
|
-
options[:trace_ids] = bound_trace_ids(registration.client, options[:trace_ids], bound, only_with_assertions
|
|
196
|
+
options[:trace_ids] = bound_trace_ids(registration.client, options[:trace_ids], bound, only_with_assertions,
|
|
197
|
+
category_ids)
|
|
183
198
|
end
|
|
184
199
|
elsif bounded_dataset_ids
|
|
185
200
|
if bound
|
|
186
|
-
pinned = pinned_dataset_members(registration.client, bounded_dataset_ids, bound, only_with_assertions
|
|
201
|
+
pinned = pinned_dataset_members(registration.client, bounded_dataset_ids, bound, only_with_assertions,
|
|
202
|
+
category_ids)
|
|
187
203
|
options[:trace_ids] = pinned if pinned
|
|
188
204
|
end
|
|
189
205
|
else
|
|
190
206
|
options[:limit] = bound || 10
|
|
191
207
|
end
|
|
192
208
|
|
|
193
|
-
%i[name notes metadata max_concurrency experiment_group_id experiment_group_name dataset_ids grader_ids mock attempts only_with_assertions skip_assertion_judging dry_run].each do |key|
|
|
209
|
+
%i[name notes metadata max_concurrency experiment_group_id experiment_group_name dataset_ids grader_ids mock attempts only_with_assertions category_ids skip_assertion_judging dry_run].each do |key|
|
|
194
210
|
options[key] = args[key] unless args[key].nil?
|
|
195
211
|
end
|
|
196
212
|
|
|
@@ -363,6 +379,11 @@ module Bitfab
|
|
|
363
379
|
options.on("--grader-ids IDS") { |value| args[:grader_ids] = comma_separated("--grader-ids", value) }
|
|
364
380
|
options.on("--attempts N", Integer) { |value| args[:attempts] = positive_integer("--attempts", value) }
|
|
365
381
|
options.on("--only-with-assertions") { args[:only_with_assertions] = true }
|
|
382
|
+
options.on("--category-ids id1,id2",
|
|
383
|
+
"With --trace-ids or --dataset-ids: replay only the traces carrying an approved assertion in one of " \
|
|
384
|
+
"these categories; which assertions are judged stays the same") do |value|
|
|
385
|
+
args[:category_ids] = comma_separated("--category-ids", value)
|
|
386
|
+
end
|
|
366
387
|
options.on("--skip-assertion-judging",
|
|
367
388
|
"Don't judge approved assertions on each replay; judging is on by default and costs model calls") { args[:skip_assertion_judging] = true }
|
|
368
389
|
options.on("--judge-assertions", "Deprecated: judging is on by default") { args[:judge_assertions] = true }
|
data/lib/bitfab/scenarios.rb
CHANGED
|
@@ -26,11 +26,17 @@ module Bitfab
|
|
|
26
26
|
# again. "scenarioId" is nil while the trace has no scenario yet, and "creationStatus" is the scenario's creation
|
|
27
27
|
# status right after the call.
|
|
28
28
|
#
|
|
29
|
+
# regenerate: true builds a scenario the trace already has again: its name, description, trigger, data, and
|
|
30
|
+
# actual outcome are cleared and built over, and the organization's scenario callback, when one is set up, is
|
|
31
|
+
# asked again. Its categories, review status, labels, and assertions are kept, and asking while it is
|
|
32
|
+
# generating starts nothing more. Leaving it out leaves an existing scenario as it is.
|
|
33
|
+
#
|
|
29
34
|
# A replay, a trace outside the organization, or a trace Bitfab cannot build a scenario for (not
|
|
30
35
|
# noah-agent-turn and no scenario callback) raises an error. Adding a trace to a dataset starts the same build
|
|
31
36
|
# only when the organization has a scenario callback.
|
|
32
|
-
def generate_scenario(trace_id)
|
|
33
|
-
|
|
37
|
+
def generate_scenario(trace_id, regenerate: nil)
|
|
38
|
+
payload = regenerate.nil? ? {} : {regenerate:}
|
|
39
|
+
@http_client.request("#{scenario_path(trace_id)}/generate", payload)["generation"]
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
# Updates the scenario built from trace_id and returns the saved hash.
|
data/lib/bitfab/version.rb
CHANGED