@bitfab/sdk 0.63.1 → 0.63.3

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/index.d.cts CHANGED
@@ -697,7 +697,7 @@ declare class HttpClient {
697
697
  * Start a replay session by fetching historical traces.
698
698
  * Blocking call - creates an experiment and returns lightweight item references.
699
699
  */
700
- 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, skipAssertionJudging?: boolean, experimentalSelectiveReplay?: SelectiveReplayOptions, notes?: string, metadata?: Record<string, string>): Promise<StartReplayResponse>;
700
+ 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, skipAssertionJudging?: boolean, experimentalSelectiveReplay?: SelectiveReplayOptions, notes?: string, metadata?: Record<string, string>, dryRun?: boolean): Promise<StartReplayResponse>;
701
701
  resumeReplay(experimentId: string, traceFunctionKey: string, codeChangeFiles?: CodeChangeFile[] | null, force?: boolean): Promise<ResumeReplayResponse>;
702
702
  /**
703
703
  * Fetch an external span by ID.
@@ -774,8 +774,9 @@ interface CodeChangeFile {
774
774
  after: string;
775
775
  }
776
776
  interface StartReplayResponse {
777
- experimentId: string;
778
- experimentUrl: string;
777
+ /** Null for a dry run, which the server records no experiment for. */
778
+ experimentId: string | null;
779
+ experimentUrl: string | null;
779
780
  attempts?: number;
780
781
  items: Array<{
781
782
  selectiveReplayPlan?: SelectiveReplayPlan;
@@ -2251,7 +2252,9 @@ interface ReplayOptions {
2251
2252
  * Selection, span fetch, deserialization, and `adaptInputs` all run, so each
2252
2253
  * item reports the exact arguments the function would have received. Nothing
2253
2254
  * executes and no replay traces are produced, which is the cheap way to check
2254
- * that recorded inputs still fit the current signature.
2255
+ * that recorded inputs still fit the current signature. No experiment is
2256
+ * created either, so the result's `experimentId` and `experimentUrl` are null
2257
+ * and `onExperimentStart` is not called.
2255
2258
  */
2256
2259
  dryRun?: boolean;
2257
2260
  /**
@@ -2301,10 +2304,10 @@ interface ReplayExperiment {
2301
2304
  /** Emitted through {@link ReplayOptions.onItemStart} when a worker starts an item. */
2302
2305
  interface ReplayItemStartProgress {
2303
2306
  type: "started";
2304
- /** Experiment ID created for this replay. */
2305
- experimentId: string;
2307
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2308
+ experimentId: string | null;
2306
2309
  /** @deprecated Use {@link experimentId}. Same value. */
2307
- testRunId: string;
2310
+ testRunId: string | null;
2308
2311
  /** Items whose processing has started so far. */
2309
2312
  started: number;
2310
2313
  /** Items that have finished so far, whether they succeeded or errored. */
@@ -2330,10 +2333,10 @@ interface ReplayItemStartProgress {
2330
2333
  interface ReplayItemFinishProgress {
2331
2334
  /** Event kind, omitted for backward-compatible per-item events. */
2332
2335
  type?: "item";
2333
- /** Experiment ID created for this replay. */
2334
- experimentId: string;
2336
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2337
+ experimentId: string | null;
2335
2338
  /** @deprecated Use {@link experimentId}. Same value. */
2336
- testRunId: string;
2339
+ testRunId: string | null;
2337
2340
  /** Items that have finished so far, whether they succeeded or errored. */
2338
2341
  completed: number;
2339
2342
  /** Total number of items in this replay run. */
@@ -2401,9 +2404,10 @@ interface ReplayProgressItem {
2401
2404
  interface ReplayProgress {
2402
2405
  type?: "item" | "complete";
2403
2406
  result?: ReplayResult<unknown>;
2404
- experimentId?: string;
2407
+ /** Null for a dry run, which creates no experiment. */
2408
+ experimentId?: string | null;
2405
2409
  /** @deprecated Use {@link experimentId}. Same value. */
2406
- testRunId?: string;
2410
+ testRunId?: string | null;
2407
2411
  completed: number;
2408
2412
  total: number;
2409
2413
  succeeded: number;
@@ -2553,14 +2557,17 @@ interface ReplayItem<T> {
2553
2557
  interface ReplayResult<T> {
2554
2558
  /** Individual replay items with inputs, results, and comparison data. */
2555
2559
  items: ReplayItem<T>[];
2556
- /** The experiment ID created on the server. */
2557
- experimentId: string;
2558
- /** Full URL to view the experiment in the dashboard. */
2559
- experimentUrl: string;
2560
+ /**
2561
+ * The experiment ID created on the server. Null for a dry run, which
2562
+ * executes nothing and so creates no experiment.
2563
+ */
2564
+ experimentId: string | null;
2565
+ /** Full URL to view the experiment in the dashboard. Null for a dry run. */
2566
+ experimentUrl: string | null;
2560
2567
  /** @deprecated Use {@link experimentId}. Same value. */
2561
- testRunId: string;
2568
+ testRunId: string | null;
2562
2569
  /** @deprecated Use {@link experimentUrl}. Same value. */
2563
- testRunUrl: string;
2570
+ testRunUrl: string | null;
2564
2571
  attempts: number;
2565
2572
  }
2566
2573
  /**
@@ -3973,7 +3980,7 @@ interface CommitRef {
3973
3980
  /**
3974
3981
  * SDK version from package.json (injected at build time)
3975
3982
  */
3976
- declare const __version__ = "0.63.1";
3983
+ declare const __version__ = "0.63.3";
3977
3984
 
3978
3985
  /**
3979
3986
  * Constants for the Bitfab SDK.
package/dist/index.d.ts CHANGED
@@ -697,7 +697,7 @@ declare class HttpClient {
697
697
  * Start a replay session by fetching historical traces.
698
698
  * Blocking call - creates an experiment and returns lightweight item references.
699
699
  */
700
- 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, skipAssertionJudging?: boolean, experimentalSelectiveReplay?: SelectiveReplayOptions, notes?: string, metadata?: Record<string, string>): Promise<StartReplayResponse>;
700
+ 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, skipAssertionJudging?: boolean, experimentalSelectiveReplay?: SelectiveReplayOptions, notes?: string, metadata?: Record<string, string>, dryRun?: boolean): Promise<StartReplayResponse>;
701
701
  resumeReplay(experimentId: string, traceFunctionKey: string, codeChangeFiles?: CodeChangeFile[] | null, force?: boolean): Promise<ResumeReplayResponse>;
702
702
  /**
703
703
  * Fetch an external span by ID.
@@ -774,8 +774,9 @@ interface CodeChangeFile {
774
774
  after: string;
775
775
  }
776
776
  interface StartReplayResponse {
777
- experimentId: string;
778
- experimentUrl: string;
777
+ /** Null for a dry run, which the server records no experiment for. */
778
+ experimentId: string | null;
779
+ experimentUrl: string | null;
779
780
  attempts?: number;
780
781
  items: Array<{
781
782
  selectiveReplayPlan?: SelectiveReplayPlan;
@@ -2251,7 +2252,9 @@ interface ReplayOptions {
2251
2252
  * Selection, span fetch, deserialization, and `adaptInputs` all run, so each
2252
2253
  * item reports the exact arguments the function would have received. Nothing
2253
2254
  * executes and no replay traces are produced, which is the cheap way to check
2254
- * that recorded inputs still fit the current signature.
2255
+ * that recorded inputs still fit the current signature. No experiment is
2256
+ * created either, so the result's `experimentId` and `experimentUrl` are null
2257
+ * and `onExperimentStart` is not called.
2255
2258
  */
2256
2259
  dryRun?: boolean;
2257
2260
  /**
@@ -2301,10 +2304,10 @@ interface ReplayExperiment {
2301
2304
  /** Emitted through {@link ReplayOptions.onItemStart} when a worker starts an item. */
2302
2305
  interface ReplayItemStartProgress {
2303
2306
  type: "started";
2304
- /** Experiment ID created for this replay. */
2305
- experimentId: string;
2307
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2308
+ experimentId: string | null;
2306
2309
  /** @deprecated Use {@link experimentId}. Same value. */
2307
- testRunId: string;
2310
+ testRunId: string | null;
2308
2311
  /** Items whose processing has started so far. */
2309
2312
  started: number;
2310
2313
  /** Items that have finished so far, whether they succeeded or errored. */
@@ -2330,10 +2333,10 @@ interface ReplayItemStartProgress {
2330
2333
  interface ReplayItemFinishProgress {
2331
2334
  /** Event kind, omitted for backward-compatible per-item events. */
2332
2335
  type?: "item";
2333
- /** Experiment ID created for this replay. */
2334
- experimentId: string;
2336
+ /** Experiment ID created for this replay. Null for a dry run, which creates none. */
2337
+ experimentId: string | null;
2335
2338
  /** @deprecated Use {@link experimentId}. Same value. */
2336
- testRunId: string;
2339
+ testRunId: string | null;
2337
2340
  /** Items that have finished so far, whether they succeeded or errored. */
2338
2341
  completed: number;
2339
2342
  /** Total number of items in this replay run. */
@@ -2401,9 +2404,10 @@ interface ReplayProgressItem {
2401
2404
  interface ReplayProgress {
2402
2405
  type?: "item" | "complete";
2403
2406
  result?: ReplayResult<unknown>;
2404
- experimentId?: string;
2407
+ /** Null for a dry run, which creates no experiment. */
2408
+ experimentId?: string | null;
2405
2409
  /** @deprecated Use {@link experimentId}. Same value. */
2406
- testRunId?: string;
2410
+ testRunId?: string | null;
2407
2411
  completed: number;
2408
2412
  total: number;
2409
2413
  succeeded: number;
@@ -2553,14 +2557,17 @@ interface ReplayItem<T> {
2553
2557
  interface ReplayResult<T> {
2554
2558
  /** Individual replay items with inputs, results, and comparison data. */
2555
2559
  items: ReplayItem<T>[];
2556
- /** The experiment ID created on the server. */
2557
- experimentId: string;
2558
- /** Full URL to view the experiment in the dashboard. */
2559
- experimentUrl: string;
2560
+ /**
2561
+ * The experiment ID created on the server. Null for a dry run, which
2562
+ * executes nothing and so creates no experiment.
2563
+ */
2564
+ experimentId: string | null;
2565
+ /** Full URL to view the experiment in the dashboard. Null for a dry run. */
2566
+ experimentUrl: string | null;
2560
2567
  /** @deprecated Use {@link experimentId}. Same value. */
2561
- testRunId: string;
2568
+ testRunId: string | null;
2562
2569
  /** @deprecated Use {@link experimentUrl}. Same value. */
2563
- testRunUrl: string;
2570
+ testRunUrl: string | null;
2564
2571
  attempts: number;
2565
2572
  }
2566
2573
  /**
@@ -3973,7 +3980,7 @@ interface CommitRef {
3973
3980
  /**
3974
3981
  * SDK version from package.json (injected at build time)
3975
3982
  */
3976
- declare const __version__ = "0.63.1";
3983
+ declare const __version__ = "0.63.3";
3977
3984
 
3978
3985
  /**
3979
3986
  * Constants for the Bitfab SDK.
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  getCurrentTrace,
28
28
  reseedFromRegistry,
29
29
  seedFromRegistry
30
- } from "./chunk-M22HAOF3.js";
30
+ } from "./chunk-7XTWASGH.js";
31
31
  import "./chunk-YWXQM6J3.js";
32
32
  import {
33
33
  BITFAB_PROGRESS_PREFIX,
@@ -36,7 +36,7 @@ import {
36
36
  ReplayError,
37
37
  reportReplayProgress,
38
38
  serializeReplayResult
39
- } from "./chunk-46UTCJLC.js";
39
+ } from "./chunk-FD2TNC5C.js";
40
40
  import {
41
41
  BitfabError,
42
42
  DEFAULT_SERVICE_URL,
@@ -44,7 +44,7 @@ import {
44
44
  MixedTracingError,
45
45
  __version__,
46
46
  flushTraces
47
- } from "./chunk-ZNQXQRQF.js";
47
+ } from "./chunk-KMK7HEFM.js";
48
48
  import "./chunk-MT36GJMW.js";
49
49
  export {
50
50
  AssertionCategoriesClient,
package/dist/node.cjs CHANGED
@@ -88,7 +88,7 @@ var __version__, __packageName__;
88
88
  var init_version_generated = __esm({
89
89
  "src/version.generated.ts"() {
90
90
  "use strict";
91
- __version__ = "0.63.1";
91
+ __version__ = "0.63.3";
92
92
  __packageName__ = "@bitfab/sdk";
93
93
  }
94
94
  });
@@ -2902,7 +2902,7 @@ var init_http = __esm({
2902
2902
  * Start a replay session by fetching historical traces.
2903
2903
  * Blocking call - creates an experiment and returns lightweight item references.
2904
2904
  */
2905
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, skipAssertionJudging, experimentalSelectiveReplay, notes, metadata) {
2905
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, skipAssertionJudging, experimentalSelectiveReplay, notes, metadata, dryRun) {
2906
2906
  const payload = { traceFunctionKey };
2907
2907
  if (experimentalSelectiveReplay !== void 0) {
2908
2908
  payload.experimentalSelectiveReplay = experimentalSelectiveReplay;
@@ -2960,6 +2960,9 @@ var init_http = __esm({
2960
2960
  if (skipAssertionJudging !== true) {
2961
2961
  payload.judgeAssertions = true;
2962
2962
  }
2963
+ if (dryRun) {
2964
+ payload.dryRun = true;
2965
+ }
2963
2966
  const git = await resolvedGitState();
2964
2967
  if (git && !isEmptyGitState(git)) {
2965
2968
  payload.git = git;
@@ -2973,7 +2976,10 @@ var init_http = __esm({
2973
2976
  const { testRunId, testRunUrl, ...rest } = response;
2974
2977
  const experimentId = response.experimentId ?? testRunId;
2975
2978
  const experimentUrl = response.experimentUrl ?? testRunUrl;
2976
- if (experimentId === void 0 || experimentUrl === void 0) {
2979
+ if (dryRun && response.experimentId === null) {
2980
+ return { ...rest, experimentId: null, experimentUrl: null };
2981
+ }
2982
+ if (experimentId === void 0 || experimentId === null || experimentUrl === void 0 || experimentUrl === null) {
2977
2983
  throw new BitfabError(
2978
2984
  "Replay start response is missing the experiment ID or URL."
2979
2985
  );
@@ -4309,7 +4315,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
4309
4315
  const originalTraceId = serverItem.originalTraceId ?? serverItem.sourceTraceId;
4310
4316
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
4311
4317
  try {
4312
- if (includeDbBranchLease && !lease && !leaseError) {
4318
+ if (includeDbBranchLease && experimentId !== null && !lease && !leaseError) {
4313
4319
  let resolved2;
4314
4320
  try {
4315
4321
  resolved2 = await httpClient.resolveDbBranchLease(
@@ -4403,7 +4409,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
4403
4409
  }
4404
4410
  return pending;
4405
4411
  } : void 0;
4406
- if (dryRun) {
4412
+ if (dryRun || experimentId === null) {
4407
4413
  return {
4408
4414
  traceId: null,
4409
4415
  originalTraceId,
@@ -4691,7 +4697,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4691
4697
  options?.skipAssertionJudging === true || options?.judgeAssertions === false,
4692
4698
  options?.experimentalSelectiveReplay,
4693
4699
  options?.notes,
4694
- options?.metadata
4700
+ options?.metadata,
4701
+ options?.dryRun === true
4695
4702
  );
4696
4703
  if (started.items.length === 0) {
4697
4704
  try {
@@ -4721,6 +4728,22 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4721
4728
  );
4722
4729
  }
4723
4730
  const { experimentId } = session;
4731
+ if (experimentId === null || session.experimentUrl === null) {
4732
+ return runReplaySession(
4733
+ httpClient,
4734
+ fn,
4735
+ session,
4736
+ null,
4737
+ maxConcurrency,
4738
+ () => {
4739
+ },
4740
+ () => {
4741
+ },
4742
+ () => false,
4743
+ options,
4744
+ registeredOverrides
4745
+ );
4746
+ }
4724
4747
  const fullExperimentUrl = `${serviceUrl}${session.experimentUrl}`;
4725
4748
  const heartbeat = startReplayHeartbeat(
4726
4749
  () => httpClient.heartbeatReplay(experimentId)
@@ -4782,12 +4805,14 @@ function throwIfInterrupted(interrupted, items, experimentId, experimentUrl) {
4782
4805
  async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxConcurrency, stopInterruptingOnSignal, markCompleteReturned, interrupted, options, registeredOverrides) {
4783
4806
  const { experimentId, attempts } = session;
4784
4807
  const mockStrategy = options?.mock ?? "marked";
4785
- try {
4786
- options?.onExperimentStart?.({
4787
- experimentId,
4788
- experimentUrl: fullExperimentUrl
4789
- });
4790
- } catch {
4808
+ if (experimentId !== null && fullExperimentUrl !== null) {
4809
+ try {
4810
+ options?.onExperimentStart?.({
4811
+ experimentId,
4812
+ experimentUrl: fullExperimentUrl
4813
+ });
4814
+ } catch {
4815
+ }
4791
4816
  }
4792
4817
  const resolvedOverrides = [
4793
4818
  ...normalizeMockOverrides(options?.mockOverride),
@@ -4929,17 +4954,18 @@ async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxC
4929
4954
  interrupted
4930
4955
  );
4931
4956
  const resultItems = [...carriedOverItems, ...ranItems];
4932
- throwIfInterrupted(interrupted, resultItems, experimentId, fullExperimentUrl);
4933
- if (options?.dryRun === true) {
4934
- throwIfInterrupted(
4935
- interrupted,
4936
- resultItems,
4937
- experimentId,
4938
- fullExperimentUrl
4939
- );
4940
- stopInterruptingOnSignal();
4941
- await httpClient.completeReplay(experimentId).catch(() => void 0);
4942
- markCompleteReturned();
4957
+ if (options?.dryRun === true || experimentId === null || fullExperimentUrl === null) {
4958
+ if (experimentId !== null && fullExperimentUrl !== null) {
4959
+ throwIfInterrupted(
4960
+ interrupted,
4961
+ resultItems,
4962
+ experimentId,
4963
+ fullExperimentUrl
4964
+ );
4965
+ stopInterruptingOnSignal();
4966
+ await httpClient.completeReplay(experimentId).catch(() => void 0);
4967
+ markCompleteReturned();
4968
+ }
4943
4969
  const dryResult = {
4944
4970
  items: resultItems,
4945
4971
  experimentId,
@@ -4951,6 +4977,7 @@ async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxC
4951
4977
  await writeReplayResultFile(dryResult);
4952
4978
  return dryResult;
4953
4979
  }
4980
+ throwIfInterrupted(interrupted, resultItems, experimentId, fullExperimentUrl);
4954
4981
  const deliveredTraceIds = await preserveReplayFailure(
4955
4982
  () => waitForReplayPersistence(httpClient, experimentId, replayedTraceIds),
4956
4983
  resultItems,