bitfab 0.61.1 → 0.61.2
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-VKGLQL7V.js → chunk-A4UVO6BQ.js} +171 -48
- package/dist/chunk-A4UVO6BQ.js.map +1 -0
- package/dist/{chunk-HKUHPLAM.js → chunk-INA6W7OB.js} +42 -2
- package/dist/{chunk-HKUHPLAM.js.map → chunk-INA6W7OB.js.map} +1 -1
- package/dist/{chunk-ENHRFXCR.js → chunk-LUOCT4HG.js} +6 -6
- package/dist/{chunk-ENHRFXCR.js.map → chunk-LUOCT4HG.js.map} +1 -1
- package/dist/{chunk-S4WE6U2Y.js → chunk-MTK6PZHA.js} +122 -52
- package/dist/chunk-MTK6PZHA.js.map +1 -0
- package/dist/{chunk-I5J2FDKH.js → chunk-ONZFMRRF.js} +42 -2
- package/dist/{chunk-I5J2FDKH.js.map → chunk-ONZFMRRF.js.map} +1 -1
- package/dist/{http-NY6M2AK3.js → http-2R6MSRVA.js} +2 -2
- package/dist/{http-5DA23DKC.js → http-KM6QWKAP.js} +2 -2
- package/dist/index.cjs +211 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +3 -3
- package/dist/node.cjs +211 -48
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +3 -3
- package/dist/{replay-KVENJRCX.js → replay-6UUBJBLK.js} +3 -3
- package/dist/replayCli.js +4 -3
- package/dist/replayCli.js.map +1 -1
- package/dist/seedCli.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-S4WE6U2Y.js.map +0 -1
- package/dist/chunk-VKGLQL7V.js.map +0 -1
- /package/dist/{http-5DA23DKC.js.map → http-2R6MSRVA.js.map} +0 -0
- /package/dist/{http-NY6M2AK3.js.map → http-KM6QWKAP.js.map} +0 -0
- /package/dist/{replay-KVENJRCX.js.map → replay-6UUBJBLK.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -603,6 +603,7 @@ declare class HttpClient {
|
|
|
603
603
|
* Blocking call - creates an experiment and returns lightweight item references.
|
|
604
604
|
*/
|
|
605
605
|
startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetIds?: string[], graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number, includeOriginalMetadata?: boolean, onlyWithAssertions?: boolean, judgeAssertions?: boolean): Promise<StartReplayResponse>;
|
|
606
|
+
resumeReplay(experimentId: string, traceFunctionKey: string, codeChangeFiles?: CodeChangeFile[] | null, force?: boolean): Promise<ResumeReplayResponse>;
|
|
606
607
|
/**
|
|
607
608
|
* Fetch an external span by ID.
|
|
608
609
|
* Blocking GET request.
|
|
@@ -748,6 +749,28 @@ interface StartReplayResponse {
|
|
|
748
749
|
originalMetadata?: Record<string, unknown>;
|
|
749
750
|
}>;
|
|
750
751
|
}
|
|
752
|
+
type StartReplayItem = StartReplayResponse["items"][number];
|
|
753
|
+
interface ResumeReplayWorkPair {
|
|
754
|
+
itemIndex: number;
|
|
755
|
+
attempt: number;
|
|
756
|
+
}
|
|
757
|
+
interface ResumeReplayFinishedItem {
|
|
758
|
+
originalTraceId: string;
|
|
759
|
+
attempt: number;
|
|
760
|
+
traceId: string;
|
|
761
|
+
hasError: boolean;
|
|
762
|
+
}
|
|
763
|
+
interface ResumeReplayResponse {
|
|
764
|
+
experimentId: string;
|
|
765
|
+
experimentUrl: string;
|
|
766
|
+
attempts: number;
|
|
767
|
+
items: StartReplayItem[];
|
|
768
|
+
work: ResumeReplayWorkPair[];
|
|
769
|
+
finished: ResumeReplayFinishedItem[];
|
|
770
|
+
skippedOriginalTraceIds: string[];
|
|
771
|
+
includeDbBranchLease: boolean;
|
|
772
|
+
dbBranchSettings: DbBranchSettings | null;
|
|
773
|
+
}
|
|
751
774
|
interface ExternalSpanResponse {
|
|
752
775
|
id: string;
|
|
753
776
|
externalTraceId: string;
|
|
@@ -2046,6 +2069,8 @@ interface ReplayOptions {
|
|
|
2046
2069
|
* callback never crashes the run.
|
|
2047
2070
|
*/
|
|
2048
2071
|
onExperimentStart?: (experiment: ReplayExperiment) => void;
|
|
2072
|
+
resume?: string;
|
|
2073
|
+
force?: boolean;
|
|
2049
2074
|
}
|
|
2050
2075
|
/** The experiment a replay records into, passed to {@link ReplayOptions.onExperimentStart}. */
|
|
2051
2076
|
interface ReplayExperiment {
|
|
@@ -2304,6 +2329,7 @@ interface ReplayItem<T> {
|
|
|
2304
2329
|
dbBranchTimings: DbBranchTimings | null;
|
|
2305
2330
|
traceOutline: TraceOutline | null;
|
|
2306
2331
|
originalTraceOutline: TraceOutline | null;
|
|
2332
|
+
carriedOver?: boolean;
|
|
2307
2333
|
}
|
|
2308
2334
|
|
|
2309
2335
|
interface ReplayResult<T> {
|
|
@@ -3719,7 +3745,7 @@ interface CommitRef {
|
|
|
3719
3745
|
/**
|
|
3720
3746
|
* SDK version from package.json (injected at build time)
|
|
3721
3747
|
*/
|
|
3722
|
-
declare const __version__ = "0.61.
|
|
3748
|
+
declare const __version__ = "0.61.2";
|
|
3723
3749
|
|
|
3724
3750
|
/**
|
|
3725
3751
|
* Constants for the Bitfab SDK.
|
package/dist/index.d.ts
CHANGED
|
@@ -603,6 +603,7 @@ declare class HttpClient {
|
|
|
603
603
|
* Blocking call - creates an experiment and returns lightweight item references.
|
|
604
604
|
*/
|
|
605
605
|
startReplay(traceFunctionKey: string, limit: number | undefined, traceIds?: string[], name?: string, codeChangeDescription?: string | null, codeChangeFiles?: CodeChangeFile[] | null, includeDbBranchLease?: boolean, experimentGroupId?: string, datasetIds?: string[], graderIds?: string[], dbBranchSettings?: DbBranchSettings, attempts?: number, includeOriginalMetadata?: boolean, onlyWithAssertions?: boolean, judgeAssertions?: boolean): Promise<StartReplayResponse>;
|
|
606
|
+
resumeReplay(experimentId: string, traceFunctionKey: string, codeChangeFiles?: CodeChangeFile[] | null, force?: boolean): Promise<ResumeReplayResponse>;
|
|
606
607
|
/**
|
|
607
608
|
* Fetch an external span by ID.
|
|
608
609
|
* Blocking GET request.
|
|
@@ -748,6 +749,28 @@ interface StartReplayResponse {
|
|
|
748
749
|
originalMetadata?: Record<string, unknown>;
|
|
749
750
|
}>;
|
|
750
751
|
}
|
|
752
|
+
type StartReplayItem = StartReplayResponse["items"][number];
|
|
753
|
+
interface ResumeReplayWorkPair {
|
|
754
|
+
itemIndex: number;
|
|
755
|
+
attempt: number;
|
|
756
|
+
}
|
|
757
|
+
interface ResumeReplayFinishedItem {
|
|
758
|
+
originalTraceId: string;
|
|
759
|
+
attempt: number;
|
|
760
|
+
traceId: string;
|
|
761
|
+
hasError: boolean;
|
|
762
|
+
}
|
|
763
|
+
interface ResumeReplayResponse {
|
|
764
|
+
experimentId: string;
|
|
765
|
+
experimentUrl: string;
|
|
766
|
+
attempts: number;
|
|
767
|
+
items: StartReplayItem[];
|
|
768
|
+
work: ResumeReplayWorkPair[];
|
|
769
|
+
finished: ResumeReplayFinishedItem[];
|
|
770
|
+
skippedOriginalTraceIds: string[];
|
|
771
|
+
includeDbBranchLease: boolean;
|
|
772
|
+
dbBranchSettings: DbBranchSettings | null;
|
|
773
|
+
}
|
|
751
774
|
interface ExternalSpanResponse {
|
|
752
775
|
id: string;
|
|
753
776
|
externalTraceId: string;
|
|
@@ -2046,6 +2069,8 @@ interface ReplayOptions {
|
|
|
2046
2069
|
* callback never crashes the run.
|
|
2047
2070
|
*/
|
|
2048
2071
|
onExperimentStart?: (experiment: ReplayExperiment) => void;
|
|
2072
|
+
resume?: string;
|
|
2073
|
+
force?: boolean;
|
|
2049
2074
|
}
|
|
2050
2075
|
/** The experiment a replay records into, passed to {@link ReplayOptions.onExperimentStart}. */
|
|
2051
2076
|
interface ReplayExperiment {
|
|
@@ -2304,6 +2329,7 @@ interface ReplayItem<T> {
|
|
|
2304
2329
|
dbBranchTimings: DbBranchTimings | null;
|
|
2305
2330
|
traceOutline: TraceOutline | null;
|
|
2306
2331
|
originalTraceOutline: TraceOutline | null;
|
|
2332
|
+
carriedOver?: boolean;
|
|
2307
2333
|
}
|
|
2308
2334
|
|
|
2309
2335
|
interface ReplayResult<T> {
|
|
@@ -3719,7 +3745,7 @@ interface CommitRef {
|
|
|
3719
3745
|
/**
|
|
3720
3746
|
* SDK version from package.json (injected at build time)
|
|
3721
3747
|
*/
|
|
3722
|
-
declare const __version__ = "0.61.
|
|
3748
|
+
declare const __version__ = "0.61.2";
|
|
3723
3749
|
|
|
3724
3750
|
/**
|
|
3725
3751
|
* Constants for the Bitfab SDK.
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
getCurrentTrace,
|
|
36
36
|
reseedFromRegistry,
|
|
37
37
|
seedFromRegistry
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-LUOCT4HG.js";
|
|
39
39
|
import "./chunk-BMJNDIVA.js";
|
|
40
40
|
import {
|
|
41
41
|
BITFAB_PROGRESS_PREFIX,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
ReplayError,
|
|
45
45
|
reportReplayProgress,
|
|
46
46
|
serializeReplayResult
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-A4UVO6BQ.js";
|
|
48
48
|
import {
|
|
49
49
|
BitfabError,
|
|
50
50
|
DEFAULT_SERVICE_URL,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
MixedTracingError,
|
|
53
53
|
__version__,
|
|
54
54
|
flushTraces
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-INA6W7OB.js";
|
|
56
56
|
import "./chunk-BAOIRE5T.js";
|
|
57
57
|
export {
|
|
58
58
|
AssertionCategoriesClient,
|
package/dist/node.cjs
CHANGED
|
@@ -97,7 +97,7 @@ var __version__, __packageName__;
|
|
|
97
97
|
var init_version_generated = __esm({
|
|
98
98
|
"src/version.generated.ts"() {
|
|
99
99
|
"use strict";
|
|
100
|
-
__version__ = "0.61.
|
|
100
|
+
__version__ = "0.61.2";
|
|
101
101
|
__packageName__ = "bitfab";
|
|
102
102
|
}
|
|
103
103
|
});
|
|
@@ -2967,6 +2967,46 @@ var init_http = __esm({
|
|
|
2967
2967
|
}
|
|
2968
2968
|
return { ...rest, experimentId, experimentUrl };
|
|
2969
2969
|
}
|
|
2970
|
+
async resumeReplay(experimentId, traceFunctionKey, codeChangeFiles, force) {
|
|
2971
|
+
const payload = {
|
|
2972
|
+
experimentId,
|
|
2973
|
+
traceFunctionKey,
|
|
2974
|
+
lazyDbBranchLease: true
|
|
2975
|
+
};
|
|
2976
|
+
if (force === true) {
|
|
2977
|
+
payload.force = true;
|
|
2978
|
+
}
|
|
2979
|
+
if (codeChangeFiles !== void 0) {
|
|
2980
|
+
payload.codeChangeFiles = codeChangeFiles;
|
|
2981
|
+
}
|
|
2982
|
+
const git = await resolvedGitState();
|
|
2983
|
+
if (git && !isEmptyGitState(git)) {
|
|
2984
|
+
payload.git = git;
|
|
2985
|
+
}
|
|
2986
|
+
const response = await this.request(
|
|
2987
|
+
"/api/sdk/replay/resume",
|
|
2988
|
+
payload,
|
|
2989
|
+
{ timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS }
|
|
2990
|
+
);
|
|
2991
|
+
const { testRunId, testRunUrl, ...rest } = response;
|
|
2992
|
+
const resumedExperimentId = response.experimentId ?? testRunId;
|
|
2993
|
+
const experimentUrl = response.experimentUrl ?? testRunUrl;
|
|
2994
|
+
if (resumedExperimentId === void 0 || experimentUrl === void 0) {
|
|
2995
|
+
throw new BitfabError(
|
|
2996
|
+
"Replay resume response is missing the experiment ID or URL."
|
|
2997
|
+
);
|
|
2998
|
+
}
|
|
2999
|
+
return {
|
|
3000
|
+
...rest,
|
|
3001
|
+
experimentId: resumedExperimentId,
|
|
3002
|
+
experimentUrl,
|
|
3003
|
+
work: rest.work ?? [],
|
|
3004
|
+
finished: rest.finished ?? [],
|
|
3005
|
+
skippedOriginalTraceIds: rest.skippedOriginalTraceIds ?? [],
|
|
3006
|
+
includeDbBranchLease: rest.includeDbBranchLease ?? false,
|
|
3007
|
+
dbBranchSettings: rest.dbBranchSettings ?? null
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
2970
3010
|
/**
|
|
2971
3011
|
* Fetch an external span by ID.
|
|
2972
3012
|
* Blocking GET request.
|
|
@@ -3602,6 +3642,88 @@ function expandReplayWork(serverItems, attempts) {
|
|
|
3602
3642
|
(_, attempt) => serverItems.map((serverItem) => ({ serverItem, attempt }))
|
|
3603
3643
|
).flat();
|
|
3604
3644
|
}
|
|
3645
|
+
function validateResume(resume, options) {
|
|
3646
|
+
if (resume.trim().length === 0) {
|
|
3647
|
+
throw new BitfabError("resume must be the ID of the experiment to resume.");
|
|
3648
|
+
}
|
|
3649
|
+
const conflicting = RESUME_CONFLICTING_OPTIONS.filter(
|
|
3650
|
+
(name) => options[name] !== void 0 && options[name] !== false
|
|
3651
|
+
);
|
|
3652
|
+
if (conflicting.length > 0) {
|
|
3653
|
+
throw new BitfabError(
|
|
3654
|
+
`resume continues experiment ${resume} with the traces, attempts, and graders it started with, so it cannot be combined with ${conflicting.join(", ")}. Drop those options, or start a new replay without resume.`
|
|
3655
|
+
);
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
async function resumeReplaySession(httpClient, experimentId, traceFunctionKey, codeChangeFiles, force, requestedDbBranch) {
|
|
3659
|
+
const response = await httpClient.resumeReplay(
|
|
3660
|
+
experimentId,
|
|
3661
|
+
traceFunctionKey,
|
|
3662
|
+
codeChangeFiles,
|
|
3663
|
+
force
|
|
3664
|
+
);
|
|
3665
|
+
const work = response.work.map(({ itemIndex, attempt }) => {
|
|
3666
|
+
const serverItem = response.items[itemIndex];
|
|
3667
|
+
if (serverItem === void 0) {
|
|
3668
|
+
throw new BitfabError(
|
|
3669
|
+
`Replay resume for experiment ${response.experimentId} named item ${itemIndex}, but the server returned only ${response.items.length} item(s).`
|
|
3670
|
+
);
|
|
3671
|
+
}
|
|
3672
|
+
return { serverItem, attempt };
|
|
3673
|
+
});
|
|
3674
|
+
if (response.skippedOriginalTraceIds.length > 0) {
|
|
3675
|
+
try {
|
|
3676
|
+
console.warn(
|
|
3677
|
+
`Bitfab: ${response.skippedOriginalTraceIds.length} trace(s) selected when experiment ${response.experimentId} started no longer exist, so resume skips them: ${response.skippedOriginalTraceIds.join(", ")}`
|
|
3678
|
+
);
|
|
3679
|
+
} catch {
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
if (requestedDbBranch !== void 0 && dbBranchEnabled(requestedDbBranch) !== response.includeDbBranchLease) {
|
|
3683
|
+
try {
|
|
3684
|
+
console.warn(
|
|
3685
|
+
`Bitfab: experiment ${response.experimentId} started with database branching ${response.includeDbBranchLease ? "on" : "off"}, so resume keeps it ${response.includeDbBranchLease ? "on" : "off"} and ignores the dbBranch option passed here.`
|
|
3686
|
+
);
|
|
3687
|
+
} catch {
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
return {
|
|
3691
|
+
experimentId: response.experimentId,
|
|
3692
|
+
experimentUrl: response.experimentUrl,
|
|
3693
|
+
attempts: response.attempts,
|
|
3694
|
+
work,
|
|
3695
|
+
finished: response.finished,
|
|
3696
|
+
includeDbBranchLease: response.includeDbBranchLease,
|
|
3697
|
+
dbBranchSettings: response.dbBranchSettings ?? void 0
|
|
3698
|
+
};
|
|
3699
|
+
}
|
|
3700
|
+
function carriedOverReplayItem(finished) {
|
|
3701
|
+
return {
|
|
3702
|
+
traceId: finished.traceId,
|
|
3703
|
+
originalTraceId: finished.originalTraceId,
|
|
3704
|
+
originalSpanId: "",
|
|
3705
|
+
sourceTraceId: finished.originalTraceId,
|
|
3706
|
+
sourceSpanId: "",
|
|
3707
|
+
attempt: finished.attempt,
|
|
3708
|
+
input: [],
|
|
3709
|
+
result: void 0,
|
|
3710
|
+
originalOutput: void 0,
|
|
3711
|
+
error: finished.hasError ? CARRIED_OVER_ERROR : null,
|
|
3712
|
+
traceError: null,
|
|
3713
|
+
replayError: null,
|
|
3714
|
+
durationMs: null,
|
|
3715
|
+
originalDurationMs: null,
|
|
3716
|
+
originalTokens: null,
|
|
3717
|
+
originalModel: null,
|
|
3718
|
+
tokens: null,
|
|
3719
|
+
model: null,
|
|
3720
|
+
dbSnapshotRef: null,
|
|
3721
|
+
dbBranchTimings: null,
|
|
3722
|
+
traceOutline: null,
|
|
3723
|
+
originalTraceOutline: null,
|
|
3724
|
+
carriedOver: true
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3605
3727
|
function resolveAttempts(attempts) {
|
|
3606
3728
|
if (attempts === void 0) {
|
|
3607
3729
|
return 1;
|
|
@@ -4054,6 +4176,13 @@ async function mapWithConcurrency2(tasks, maxConcurrency, onSettled, onStarted)
|
|
|
4054
4176
|
return results;
|
|
4055
4177
|
}
|
|
4056
4178
|
async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, registeredOverrides = []) {
|
|
4179
|
+
if (options?.resume !== void 0) {
|
|
4180
|
+
validateResume(options.resume, options);
|
|
4181
|
+
} else if (options?.force === true) {
|
|
4182
|
+
throw new BitfabError(
|
|
4183
|
+
"force only applies when resuming an experiment. Pass it together with resume."
|
|
4184
|
+
);
|
|
4185
|
+
}
|
|
4057
4186
|
if (options?.traceIds !== void 0) {
|
|
4058
4187
|
if (options.traceIds.length === 0) {
|
|
4059
4188
|
throw new BitfabError("traceIds must contain at least one trace ID.");
|
|
@@ -4073,7 +4202,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4073
4202
|
} catch {
|
|
4074
4203
|
}
|
|
4075
4204
|
}
|
|
4076
|
-
const
|
|
4205
|
+
const requestedAttempts = resolveAttempts(options?.attempts);
|
|
4077
4206
|
const maxConcurrency = options?.maxConcurrency ?? 10;
|
|
4078
4207
|
if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1) {
|
|
4079
4208
|
throw new BitfabError(
|
|
@@ -4092,40 +4221,59 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4092
4221
|
}
|
|
4093
4222
|
}
|
|
4094
4223
|
}
|
|
4095
|
-
const
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4224
|
+
const includeDbBranchLease = dbBranchEnabled(options?.dbBranch) && options?.dryRun !== true;
|
|
4225
|
+
let session;
|
|
4226
|
+
if (options?.resume === void 0) {
|
|
4227
|
+
const started2 = await httpClient.startReplay(
|
|
4228
|
+
traceFunctionKey,
|
|
4229
|
+
// limit is meaningless with explicit traceIds (the ID list determines
|
|
4230
|
+
// the count), so it's omitted from the request entirely.
|
|
4231
|
+
options?.traceIds ? void 0 : options?.limit ?? 5,
|
|
4232
|
+
options?.traceIds,
|
|
4233
|
+
options?.name,
|
|
4234
|
+
codeChangeDescription,
|
|
4235
|
+
codeChangeFiles,
|
|
4236
|
+
// A dry run executes nothing, so a branch would be provisioned (and billed)
|
|
4237
|
+
// for code that never runs, and a seeded source's refusal would fail the item
|
|
4238
|
+
// before it could report its resolved inputs.
|
|
4239
|
+
includeDbBranchLease,
|
|
4240
|
+
options?.experimentGroupId,
|
|
4241
|
+
datasetIds,
|
|
4242
|
+
options?.graderIds,
|
|
4243
|
+
resolveDbBranchSettings(options?.dbBranch),
|
|
4244
|
+
requestedAttempts,
|
|
4245
|
+
options?.adaptInputs !== void 0,
|
|
4246
|
+
options?.onlyWithAssertions,
|
|
4247
|
+
options?.judgeAssertions
|
|
4248
|
+
);
|
|
4249
|
+
if (started2.items.length === 0) {
|
|
4250
|
+
try {
|
|
4251
|
+
console.warn(
|
|
4252
|
+
`Bitfab: no traces matched "${traceFunctionKey}", so this replay ran nothing. Capture a trace, or seed one with seedTrace, before replaying.`
|
|
4253
|
+
);
|
|
4254
|
+
} catch {
|
|
4255
|
+
}
|
|
4127
4256
|
}
|
|
4257
|
+
session = {
|
|
4258
|
+
experimentId: started2.experimentId,
|
|
4259
|
+
experimentUrl: started2.experimentUrl,
|
|
4260
|
+
attempts: requestedAttempts,
|
|
4261
|
+
work: expandReplayWork(started2.items, requestedAttempts),
|
|
4262
|
+
finished: [],
|
|
4263
|
+
includeDbBranchLease,
|
|
4264
|
+
dbBranchSettings: resolveDbBranchSettings(options?.dbBranch)
|
|
4265
|
+
};
|
|
4266
|
+
} else {
|
|
4267
|
+
session = await resumeReplaySession(
|
|
4268
|
+
httpClient,
|
|
4269
|
+
options.resume,
|
|
4270
|
+
traceFunctionKey,
|
|
4271
|
+
codeChangeFiles,
|
|
4272
|
+
options.force,
|
|
4273
|
+
options.dbBranch
|
|
4274
|
+
);
|
|
4128
4275
|
}
|
|
4276
|
+
const { experimentId, experimentUrl, attempts } = session;
|
|
4129
4277
|
const mockStrategy = options?.mock ?? "marked";
|
|
4130
4278
|
const fullExperimentUrl = `${serviceUrl}${experimentUrl}`;
|
|
4131
4279
|
try {
|
|
@@ -4139,7 +4287,10 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4139
4287
|
...normalizeMockOverrides(options?.mockOverride),
|
|
4140
4288
|
...registeredOverrides
|
|
4141
4289
|
];
|
|
4142
|
-
const workItems =
|
|
4290
|
+
const workItems = session.work;
|
|
4291
|
+
const carriedOverItems = session.finished.map(
|
|
4292
|
+
(finished) => carriedOverReplayItem(finished)
|
|
4293
|
+
);
|
|
4143
4294
|
const replayedTraceIds = workItems.map(() => randomUuid());
|
|
4144
4295
|
httpClient.trackTraceDeliveries(replayedTraceIds);
|
|
4145
4296
|
const tasks = workItems.map(
|
|
@@ -4152,18 +4303,18 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4152
4303
|
resolvedOverrides,
|
|
4153
4304
|
replayedTraceIds[index],
|
|
4154
4305
|
attempt,
|
|
4155
|
-
|
|
4156
|
-
|
|
4306
|
+
session.includeDbBranchLease,
|
|
4307
|
+
session.dbBranchSettings,
|
|
4157
4308
|
options?.adaptInputs,
|
|
4158
4309
|
options?.dryRun === true
|
|
4159
4310
|
)
|
|
4160
4311
|
);
|
|
4161
|
-
const total = tasks.length;
|
|
4312
|
+
const total = tasks.length + carriedOverItems.length;
|
|
4162
4313
|
const onItemFinish = options?.onItemFinish ?? options?.onProgress;
|
|
4163
|
-
let completed =
|
|
4164
|
-
let started =
|
|
4165
|
-
let
|
|
4166
|
-
let
|
|
4314
|
+
let completed = carriedOverItems.length;
|
|
4315
|
+
let started = carriedOverItems.length;
|
|
4316
|
+
let errored = carriedOverItems.filter((item) => item.error !== null).length;
|
|
4317
|
+
let succeeded = completed - errored;
|
|
4167
4318
|
let flushInFlight = null;
|
|
4168
4319
|
let flushPending = false;
|
|
4169
4320
|
const flushFinishedItemTrace = () => {
|
|
@@ -4183,7 +4334,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4183
4334
|
}
|
|
4184
4335
|
return flushInFlight;
|
|
4185
4336
|
};
|
|
4186
|
-
const
|
|
4337
|
+
const ranItems = await mapWithConcurrency2(
|
|
4187
4338
|
tasks,
|
|
4188
4339
|
maxConcurrency,
|
|
4189
4340
|
async (item, index) => {
|
|
@@ -4270,6 +4421,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4270
4421
|
}
|
|
4271
4422
|
} : void 0
|
|
4272
4423
|
);
|
|
4424
|
+
const resultItems = [...carriedOverItems, ...ranItems];
|
|
4273
4425
|
if (options?.dryRun === true) {
|
|
4274
4426
|
await httpClient.completeReplay(experimentId).catch(() => void 0);
|
|
4275
4427
|
const dryResult = {
|
|
@@ -4289,11 +4441,11 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4289
4441
|
experimentId,
|
|
4290
4442
|
fullExperimentUrl
|
|
4291
4443
|
);
|
|
4292
|
-
for (let index = 0; index <
|
|
4444
|
+
for (let index = 0; index < ranItems.length; index += 1) {
|
|
4293
4445
|
const localId = replayedTraceIds[index];
|
|
4294
4446
|
const readBack = localId ? deliveredTraceIds[localId] : void 0;
|
|
4295
4447
|
if (readBack !== void 0) {
|
|
4296
|
-
|
|
4448
|
+
ranItems[index].traceId = readBack;
|
|
4297
4449
|
}
|
|
4298
4450
|
}
|
|
4299
4451
|
const completeResult = await preserveReplayFailure(
|
|
@@ -4307,8 +4459,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
4307
4459
|
if (serverTraceIds !== void 0) {
|
|
4308
4460
|
const missing = [];
|
|
4309
4461
|
let completedCount = 0;
|
|
4310
|
-
for (let index = 0; index <
|
|
4311
|
-
const item =
|
|
4462
|
+
for (let index = 0; index < ranItems.length; index += 1) {
|
|
4463
|
+
const item = ranItems[index];
|
|
4312
4464
|
const localId = replayedTraceIds[index];
|
|
4313
4465
|
const mapped = localId ? serverTraceIds[localId] : void 0;
|
|
4314
4466
|
item.traceId = item.traceId ?? mapped ?? null;
|
|
@@ -4394,7 +4546,7 @@ async function writeReplayResultFile(result) {
|
|
|
4394
4546
|
}
|
|
4395
4547
|
}
|
|
4396
4548
|
}
|
|
4397
|
-
var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
|
|
4549
|
+
var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, RESUME_CONFLICTING_OPTIONS, CARRIED_OVER_ERROR, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError;
|
|
4398
4550
|
var init_replay = __esm({
|
|
4399
4551
|
"src/replay.ts"() {
|
|
4400
4552
|
"use strict";
|
|
@@ -4408,6 +4560,17 @@ var init_replay = __esm({
|
|
|
4408
4560
|
init_serialize();
|
|
4409
4561
|
REPLAY_PERSISTENCE_TIMEOUT_MS = 3e4;
|
|
4410
4562
|
MAX_REPLAY_ATTEMPTS = 100;
|
|
4563
|
+
RESUME_CONFLICTING_OPTIONS = [
|
|
4564
|
+
"traceIds",
|
|
4565
|
+
"limit",
|
|
4566
|
+
"datasetId",
|
|
4567
|
+
"datasetIds",
|
|
4568
|
+
"attempts",
|
|
4569
|
+
"graderIds",
|
|
4570
|
+
"onlyWithAssertions",
|
|
4571
|
+
"dryRun"
|
|
4572
|
+
];
|
|
4573
|
+
CARRIED_OVER_ERROR = "This item errored in an earlier run of this experiment, before it was resumed.";
|
|
4411
4574
|
BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
|
|
4412
4575
|
ReplayError = class extends BitfabError {
|
|
4413
4576
|
constructor(message, items, experimentId, experimentUrl, cause) {
|