bitfab 0.38.9 → 0.39.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.
- package/dist/chunk-3JIPWENI.js +1856 -0
- package/dist/chunk-3JIPWENI.js.map +1 -0
- package/dist/chunk-7OKE7FGZ.js +1150 -0
- package/dist/chunk-7OKE7FGZ.js.map +1 -0
- package/dist/{chunk-EPU5AUT4.js → chunk-B4EJ2EQT.js} +113 -11
- package/dist/chunk-B4EJ2EQT.js.map +1 -0
- package/dist/{chunk-J73FXDFA.js → chunk-OXE6M7CZ.js} +21 -1102
- package/dist/chunk-OXE6M7CZ.js.map +1 -0
- package/dist/http-ALSBGWPS.js +19 -0
- package/dist/http-RMF7T3LG.js +20 -0
- package/dist/http-RMF7T3LG.js.map +1 -0
- package/dist/index.cjs +169 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -3
- package/dist/index.d.ts +98 -3
- package/dist/index.js +12 -8
- package/dist/node.cjs +169 -8
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +12 -8
- package/dist/node.js.map +1 -1
- package/dist/{replay-OFQPJZZD.js → replay-6VF5AG2X.js} +3 -2
- package/dist/replay-6VF5AG2X.js.map +1 -0
- package/dist/replayCli.js +132 -146
- package/dist/replayCli.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EPU5AUT4.js.map +0 -1
- package/dist/chunk-J73FXDFA.js.map +0 -1
- /package/dist/{replay-OFQPJZZD.js.map → http-ALSBGWPS.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -51,7 +51,7 @@ var __version__, __packageName__;
|
|
|
51
51
|
var init_version_generated = __esm({
|
|
52
52
|
"src/version.generated.ts"() {
|
|
53
53
|
"use strict";
|
|
54
|
-
__version__ = "0.
|
|
54
|
+
__version__ = "0.39.0";
|
|
55
55
|
__packageName__ = "bitfab";
|
|
56
56
|
}
|
|
57
57
|
});
|
|
@@ -1207,6 +1207,16 @@ var init_transport = __esm({
|
|
|
1207
1207
|
});
|
|
1208
1208
|
|
|
1209
1209
|
// src/http.ts
|
|
1210
|
+
var http_exports = {};
|
|
1211
|
+
__export(http_exports, {
|
|
1212
|
+
BitfabError: () => BitfabError,
|
|
1213
|
+
HttpClient: () => HttpClient,
|
|
1214
|
+
awaitOnExit: () => awaitOnExit,
|
|
1215
|
+
awaitPendingRequests: () => awaitPendingRequests,
|
|
1216
|
+
flushTraces: () => flushTraces,
|
|
1217
|
+
parseRetryAfterMs: () => parseRetryAfterMs,
|
|
1218
|
+
serializePayloadBody: () => serializePayloadBody
|
|
1219
|
+
});
|
|
1210
1220
|
function awaitOnExit(promise) {
|
|
1211
1221
|
pendingTracePromises.add(promise);
|
|
1212
1222
|
void promise.finally(() => {
|
|
@@ -2551,7 +2561,7 @@ function buildMockTree(rootNode) {
|
|
|
2551
2561
|
}
|
|
2552
2562
|
return { spans };
|
|
2553
2563
|
}
|
|
2554
|
-
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs) {
|
|
2564
|
+
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, resolvedOverrides, replayedTraceId, includeDbBranchLease, dbBranchSettings, adaptInputs, dryRun) {
|
|
2555
2565
|
let lease = includeDbBranchLease ? serverItem.dbBranchLease : void 0;
|
|
2556
2566
|
let leaseError = includeDbBranchLease ? serverItem.dbBranchLeaseError : void 0;
|
|
2557
2567
|
let dbSnapshotRef = serverItem.dbSnapshotRef;
|
|
@@ -2646,6 +2656,32 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
2646
2656
|
}
|
|
2647
2657
|
return pending;
|
|
2648
2658
|
} : void 0;
|
|
2659
|
+
if (dryRun) {
|
|
2660
|
+
return {
|
|
2661
|
+
traceId: null,
|
|
2662
|
+
originalTraceId,
|
|
2663
|
+
originalSpanId,
|
|
2664
|
+
sourceTraceId: originalTraceId,
|
|
2665
|
+
sourceSpanId: originalSpanId,
|
|
2666
|
+
input: inputs,
|
|
2667
|
+
result: void 0,
|
|
2668
|
+
originalOutput,
|
|
2669
|
+
...serverItem.ingestionType && {
|
|
2670
|
+
ingestionType: serverItem.ingestionType
|
|
2671
|
+
},
|
|
2672
|
+
error: null,
|
|
2673
|
+
traceError: null,
|
|
2674
|
+
replayError: null,
|
|
2675
|
+
durationMs: null,
|
|
2676
|
+
originalDurationMs: serverItem.originalDurationMs ?? serverItem.durationMs ?? null,
|
|
2677
|
+
originalTokens: serverItem.originalTokens ?? serverItem.tokens ?? null,
|
|
2678
|
+
originalModel: serverItem.originalModel ?? serverItem.model ?? null,
|
|
2679
|
+
tokens: null,
|
|
2680
|
+
model: serverItem.originalModel ?? serverItem.model ?? null,
|
|
2681
|
+
dbSnapshotRef: dbSnapshotRef ?? null,
|
|
2682
|
+
dbBranchTimings: dbBranchTimings ?? null
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2649
2685
|
try {
|
|
2650
2686
|
replayStarted = performance.now();
|
|
2651
2687
|
const maybePromise = runWithReplayContext(
|
|
@@ -2709,6 +2745,9 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
2709
2745
|
input: inputs,
|
|
2710
2746
|
result,
|
|
2711
2747
|
originalOutput,
|
|
2748
|
+
...serverItem.ingestionType && {
|
|
2749
|
+
ingestionType: serverItem.ingestionType
|
|
2750
|
+
},
|
|
2712
2751
|
error,
|
|
2713
2752
|
traceError,
|
|
2714
2753
|
replayError,
|
|
@@ -2856,13 +2895,23 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2856
2895
|
options?.name,
|
|
2857
2896
|
codeChangeDescription,
|
|
2858
2897
|
codeChangeFiles,
|
|
2859
|
-
|
|
2860
|
-
//
|
|
2898
|
+
// A dry run executes nothing, so a branch would be provisioned (and billed)
|
|
2899
|
+
// for code that never runs, and a seeded source's refusal would fail the item
|
|
2900
|
+
// before it could report its resolved inputs.
|
|
2901
|
+
dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
|
|
2861
2902
|
options?.experimentGroupId,
|
|
2862
2903
|
options?.datasetId,
|
|
2863
2904
|
options?.graderIds,
|
|
2864
2905
|
resolveDbBranchSettings(options?.dbBranch)
|
|
2865
2906
|
);
|
|
2907
|
+
if (serverItems.length === 0) {
|
|
2908
|
+
try {
|
|
2909
|
+
console.warn(
|
|
2910
|
+
`Bitfab: no traces matched "${traceFunctionKey}", so this replay ran nothing. Capture a trace, or seed one with seedTrace, before replaying.`
|
|
2911
|
+
);
|
|
2912
|
+
} catch {
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2866
2915
|
const mockStrategy = options?.mock ?? "marked";
|
|
2867
2916
|
const maxConcurrency = options?.maxConcurrency ?? 10;
|
|
2868
2917
|
const fullTestRunUrl = `${serviceUrl}${testRunUrl}`;
|
|
@@ -2881,9 +2930,10 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2881
2930
|
mockStrategy,
|
|
2882
2931
|
resolvedOverrides,
|
|
2883
2932
|
replayedTraceIds[index],
|
|
2884
|
-
dbBranchEnabled(options?.dbBranch),
|
|
2933
|
+
dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true,
|
|
2885
2934
|
resolveDbBranchSettings(options?.dbBranch),
|
|
2886
|
-
options?.adaptInputs
|
|
2935
|
+
options?.adaptInputs,
|
|
2936
|
+
options?.dryRun === true
|
|
2887
2937
|
)
|
|
2888
2938
|
);
|
|
2889
2939
|
const total = tasks.length;
|
|
@@ -2991,6 +3041,16 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2991
3041
|
}
|
|
2992
3042
|
} : void 0
|
|
2993
3043
|
);
|
|
3044
|
+
if (options?.dryRun === true) {
|
|
3045
|
+
await httpClient.completeReplay(testRunId).catch(() => void 0);
|
|
3046
|
+
const dryResult = {
|
|
3047
|
+
items: resultItems,
|
|
3048
|
+
testRunId,
|
|
3049
|
+
testRunUrl: fullTestRunUrl
|
|
3050
|
+
};
|
|
3051
|
+
await writeReplayResultFile(dryResult);
|
|
3052
|
+
return dryResult;
|
|
3053
|
+
}
|
|
2994
3054
|
const deliveredTraceIds = await preserveReplayFailure(
|
|
2995
3055
|
() => waitForReplayPersistence(httpClient, testRunId, replayedTraceIds),
|
|
2996
3056
|
resultItems,
|
|
@@ -3159,6 +3219,7 @@ __export(index_exports, {
|
|
|
3159
3219
|
getCurrentSpan: () => getCurrentSpan,
|
|
3160
3220
|
getCurrentTrace: () => getCurrentTrace,
|
|
3161
3221
|
reportReplayProgress: () => reportReplayProgress,
|
|
3222
|
+
seedFromRegistry: () => seedFromRegistry,
|
|
3162
3223
|
serializeReplayResult: () => serializeReplayResult
|
|
3163
3224
|
});
|
|
3164
3225
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -6171,6 +6232,7 @@ var Bitfab = class {
|
|
|
6171
6232
|
return invokeWithoutNode();
|
|
6172
6233
|
}
|
|
6173
6234
|
spansUsed += 1;
|
|
6235
|
+
const mockOnReplay = nodeConfiguration?.mockOnReplay ?? options.mockOnReplayDefault;
|
|
6174
6236
|
const childOptions = {
|
|
6175
6237
|
name: nodeConfiguration?.name ?? definition.name,
|
|
6176
6238
|
type: nodeConfiguration?.type ?? "function",
|
|
@@ -6181,8 +6243,8 @@ var Bitfab = class {
|
|
|
6181
6243
|
...nodeConfiguration?.testRunId !== void 0 && {
|
|
6182
6244
|
testRunId: nodeConfiguration.testRunId
|
|
6183
6245
|
},
|
|
6184
|
-
...
|
|
6185
|
-
mockOnReplay
|
|
6246
|
+
...mockOnReplay !== void 0 && {
|
|
6247
|
+
mockOnReplay
|
|
6186
6248
|
},
|
|
6187
6249
|
...nodeConfiguration?.finalize !== void 0 && {
|
|
6188
6250
|
finalize: nodeConfiguration.finalize
|
|
@@ -6868,6 +6930,7 @@ var Bitfab = class {
|
|
|
6868
6930
|
inputSourceTraceId: traceState?.inputSourceTraceId,
|
|
6869
6931
|
dbSnapshotRef: traceState?.dbSnapshotRef,
|
|
6870
6932
|
dropped: traceState?.dropped,
|
|
6933
|
+
ingestionType: traceState?.ingestionType,
|
|
6871
6934
|
// Built AFTER the wrapped fn finished, so `accessed` reflects
|
|
6872
6935
|
// whether customer code obtained the branch URL during this
|
|
6873
6936
|
// item. Omitted entirely when no lease was attached, so the
|
|
@@ -7091,6 +7154,7 @@ var Bitfab = class {
|
|
|
7091
7154
|
Object.defineProperty(wrappedFn, "_bitfabTraceFunctionKey", {
|
|
7092
7155
|
value: traceFunctionKey
|
|
7093
7156
|
});
|
|
7157
|
+
Object.defineProperty(wrappedFn, "_bitfabWrappedFn", { value: fn });
|
|
7094
7158
|
return wrappedFn;
|
|
7095
7159
|
}
|
|
7096
7160
|
/**
|
|
@@ -7253,6 +7317,9 @@ var Bitfab = class {
|
|
|
7253
7317
|
if (params.dbSnapshotRef) {
|
|
7254
7318
|
rawTrace.db_snapshot_ref = params.dbSnapshotRef;
|
|
7255
7319
|
}
|
|
7320
|
+
if (params.ingestionType) {
|
|
7321
|
+
rawTrace.ingestion_type = params.ingestionType;
|
|
7322
|
+
}
|
|
7256
7323
|
if (params.dbSnapshotUsage) {
|
|
7257
7324
|
rawTrace.db_snapshot_usage = {
|
|
7258
7325
|
neon_branch_id: params.dbSnapshotUsage.neonBranchId,
|
|
@@ -7399,6 +7466,68 @@ var Bitfab = class {
|
|
|
7399
7466
|
clearMockOverrides() {
|
|
7400
7467
|
this.mockOverrides.length = 0;
|
|
7401
7468
|
}
|
|
7469
|
+
/**
|
|
7470
|
+
* Write a replayable trace from a case, without running anything.
|
|
7471
|
+
*
|
|
7472
|
+
* Use this to turn a corpus you already hold (a Braintrust dataset, a
|
|
7473
|
+
* spreadsheet, hand-written cases) into traces that {@link replay} can
|
|
7474
|
+
* select. The recorded root span carries `input` as its input and `expected`
|
|
7475
|
+
* as its output, so replay reports each item against the value you expected
|
|
7476
|
+
* rather than against a previous run.
|
|
7477
|
+
*
|
|
7478
|
+
* A seeded trace has no child spans and no database pin, so replay mocking
|
|
7479
|
+
* has nothing recorded to substitute and `dbBranch` refuses it. Pass
|
|
7480
|
+
* `mockOverride` at replay time for calls that must not run.
|
|
7481
|
+
*
|
|
7482
|
+
* @returns The trace ID, usable with `replay({ traceIds: [...] })`.
|
|
7483
|
+
*/
|
|
7484
|
+
seedTrace(traceFunctionKey, options) {
|
|
7485
|
+
const { input } = options;
|
|
7486
|
+
const fn = options.fn?._bitfabWrappedFn ?? options.fn;
|
|
7487
|
+
if (fn && input.length < fn.length) {
|
|
7488
|
+
throw new BitfabError(
|
|
7489
|
+
`Seeded case supplies ${input.length} argument(s) but ${fn.name === "" ? "the function" : fn.name} requires ${fn.length}. Fix the case, or omit fn to seed it anyway.`
|
|
7490
|
+
);
|
|
7491
|
+
}
|
|
7492
|
+
const traceId = randomUuid();
|
|
7493
|
+
const startedAt = nowIsoTimestamp();
|
|
7494
|
+
activeTraceStates.set(traceId, {
|
|
7495
|
+
traceId,
|
|
7496
|
+
startedAt,
|
|
7497
|
+
contexts: [],
|
|
7498
|
+
ingestionType: "seeded",
|
|
7499
|
+
...options.sessionId !== void 0 && { sessionId: options.sessionId },
|
|
7500
|
+
...options.metadata !== void 0 && { metadata: options.metadata }
|
|
7501
|
+
});
|
|
7502
|
+
try {
|
|
7503
|
+
this.sendWrapperSpan({
|
|
7504
|
+
traceFunctionKey,
|
|
7505
|
+
spanName: options.spanName ?? traceFunctionKey,
|
|
7506
|
+
traceId,
|
|
7507
|
+
spanId: randomUuid(),
|
|
7508
|
+
parentSpanId: null,
|
|
7509
|
+
inputs: input,
|
|
7510
|
+
result: options.expected,
|
|
7511
|
+
startedAt,
|
|
7512
|
+
endedAt: startedAt,
|
|
7513
|
+
spanType: options.spanType ?? "agent",
|
|
7514
|
+
captureContent: true
|
|
7515
|
+
});
|
|
7516
|
+
this.sendTraceCompletion({
|
|
7517
|
+
traceFunctionKey,
|
|
7518
|
+
traceId,
|
|
7519
|
+
startedAt,
|
|
7520
|
+
endedAt: startedAt,
|
|
7521
|
+
sessionId: options.sessionId,
|
|
7522
|
+
metadata: options.metadata,
|
|
7523
|
+
contexts: [],
|
|
7524
|
+
ingestionType: "seeded"
|
|
7525
|
+
});
|
|
7526
|
+
} finally {
|
|
7527
|
+
activeTraceStates.delete(traceId);
|
|
7528
|
+
}
|
|
7529
|
+
return traceId;
|
|
7530
|
+
}
|
|
7402
7531
|
async replay(traceFunctionKey, fn, options) {
|
|
7403
7532
|
const wrappedKey = fn._bitfabTraceFunctionKey;
|
|
7404
7533
|
let replayFn = fn;
|
|
@@ -7659,6 +7788,37 @@ init_replay();
|
|
|
7659
7788
|
function defineReplayRegistry(registry) {
|
|
7660
7789
|
return registry;
|
|
7661
7790
|
}
|
|
7791
|
+
async function seedFromRegistry(registry, pipeline, cases) {
|
|
7792
|
+
const registration = registry[pipeline];
|
|
7793
|
+
if (registration === void 0) {
|
|
7794
|
+
throw new BitfabError(
|
|
7795
|
+
`Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`
|
|
7796
|
+
);
|
|
7797
|
+
}
|
|
7798
|
+
const traceFunctionKey = resolveTraceFunctionKey(registration);
|
|
7799
|
+
const traceIds = cases.map(
|
|
7800
|
+
(seedCase) => registration.client.seedTrace(traceFunctionKey, {
|
|
7801
|
+
input: seedCase.input,
|
|
7802
|
+
expected: seedCase.expected,
|
|
7803
|
+
fn: registration.fn,
|
|
7804
|
+
metadata: seedCase.metadata,
|
|
7805
|
+
sessionId: seedCase.sessionId
|
|
7806
|
+
})
|
|
7807
|
+
);
|
|
7808
|
+
const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
|
|
7809
|
+
await flushTraces2(3e4);
|
|
7810
|
+
return { pipeline, traceFunctionKey, traceIds };
|
|
7811
|
+
}
|
|
7812
|
+
function resolveTraceFunctionKey(registration) {
|
|
7813
|
+
const wrappedKey = registration.fn._bitfabTraceFunctionKey;
|
|
7814
|
+
const key = registration.traceFunctionKey ?? wrappedKey;
|
|
7815
|
+
if (key === void 0) {
|
|
7816
|
+
throw new BitfabError(
|
|
7817
|
+
"Replay registry entry uses a plain function. Set traceFunctionKey to the key its production handler records."
|
|
7818
|
+
);
|
|
7819
|
+
}
|
|
7820
|
+
return key;
|
|
7821
|
+
}
|
|
7662
7822
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7663
7823
|
0 && (module.exports = {
|
|
7664
7824
|
BITFAB_PROGRESS_PREFIX,
|
|
@@ -7686,6 +7846,7 @@ function defineReplayRegistry(registry) {
|
|
|
7686
7846
|
getCurrentSpan,
|
|
7687
7847
|
getCurrentTrace,
|
|
7688
7848
|
reportReplayProgress,
|
|
7849
|
+
seedFromRegistry,
|
|
7689
7850
|
serializeReplayResult
|
|
7690
7851
|
});
|
|
7691
7852
|
//# sourceMappingURL=index.cjs.map
|