@bitfab/sdk 0.64.6 → 0.64.8

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.
Files changed (34) hide show
  1. package/cloudReplay.py +3 -0
  2. package/dist/{chunk-RZDYDKTP.js → chunk-2AZMZWVJ.js} +6 -3
  3. package/dist/chunk-2AZMZWVJ.js.map +1 -0
  4. package/dist/{chunk-NPLI52PV.js → chunk-2FBHAXXP.js} +150 -3
  5. package/dist/chunk-2FBHAXXP.js.map +1 -0
  6. package/dist/{chunk-WJP4S2NP.js → chunk-C6COKMY5.js} +32 -8
  7. package/dist/chunk-C6COKMY5.js.map +1 -0
  8. package/dist/{chunk-LACTIQDT.js → chunk-D6UWKMAP.js} +39 -4
  9. package/dist/chunk-D6UWKMAP.js.map +1 -0
  10. package/dist/{chunk-6P4TTCPH.js → chunk-HEBW2JUM.js} +6 -3
  11. package/dist/{chunk-6P4TTCPH.js.map → chunk-HEBW2JUM.js.map} +1 -1
  12. package/dist/{http-HJX3DLQS.js → http-2GCHYMMN.js} +2 -2
  13. package/dist/{http-WUHILGJY.js → http-FYDY3CVR.js} +2 -2
  14. package/dist/index.cjs +189 -6
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +26 -12
  17. package/dist/index.d.ts +26 -12
  18. package/dist/index.js +3 -3
  19. package/dist/node.cjs +189 -6
  20. package/dist/node.cjs.map +1 -1
  21. package/dist/node.d.cts +1 -1
  22. package/dist/node.d.ts +1 -1
  23. package/dist/node.js +3 -3
  24. package/dist/{replay-OIY35N3F.js → replay-GUP3ZNRQ.js} +3 -3
  25. package/dist/replayCli.js +2 -2
  26. package/dist/seedCli.js +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-LACTIQDT.js.map +0 -1
  29. package/dist/chunk-NPLI52PV.js.map +0 -1
  30. package/dist/chunk-RZDYDKTP.js.map +0 -1
  31. package/dist/chunk-WJP4S2NP.js.map +0 -1
  32. /package/dist/{http-HJX3DLQS.js.map → http-2GCHYMMN.js.map} +0 -0
  33. /package/dist/{http-WUHILGJY.js.map → http-FYDY3CVR.js.map} +0 -0
  34. /package/dist/{replay-OIY35N3F.js.map → replay-GUP3ZNRQ.js.map} +0 -0
@@ -7,7 +7,7 @@ import {
7
7
  flushTraces,
8
8
  parseRetryAfterMs,
9
9
  serializePayloadBody
10
- } from "./chunk-RZDYDKTP.js";
10
+ } from "./chunk-2AZMZWVJ.js";
11
11
  import "./chunk-MT36GJMW.js";
12
12
  export {
13
13
  BitfabError,
@@ -19,4 +19,4 @@ export {
19
19
  parseRetryAfterMs,
20
20
  serializePayloadBody
21
21
  };
22
- //# sourceMappingURL=http-HJX3DLQS.js.map
22
+ //# sourceMappingURL=http-2GCHYMMN.js.map
@@ -7,7 +7,7 @@ import {
7
7
  flushTraces,
8
8
  parseRetryAfterMs,
9
9
  serializePayloadBody
10
- } from "./chunk-6P4TTCPH.js";
10
+ } from "./chunk-HEBW2JUM.js";
11
11
  export {
12
12
  BitfabError,
13
13
  HttpClient,
@@ -18,4 +18,4 @@ export {
18
18
  parseRetryAfterMs,
19
19
  serializePayloadBody
20
20
  };
21
- //# sourceMappingURL=http-WUHILGJY.js.map
21
+ //# sourceMappingURL=http-FYDY3CVR.js.map
package/dist/index.cjs CHANGED
@@ -42,7 +42,7 @@ var __version__, __packageName__;
42
42
  var init_version_generated = __esm({
43
43
  "src/version.generated.ts"() {
44
44
  "use strict";
45
- __version__ = "0.64.6";
45
+ __version__ = "0.64.8";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -2895,7 +2895,7 @@ var init_http = __esm({
2895
2895
  * Start a replay session by fetching historical traces.
2896
2896
  * Blocking call - creates an experiment and returns lightweight item references.
2897
2897
  */
2898
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, skipAssertionJudging, experimentalSelectiveReplay, notes, metadata, dryRun) {
2898
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, skipAssertionJudging, experimentalSelectiveReplay, notes, metadata, dryRun, invocation) {
2899
2899
  const payload = { traceFunctionKey };
2900
2900
  if (experimentalSelectiveReplay !== void 0) {
2901
2901
  payload.experimentalSelectiveReplay = experimentalSelectiveReplay;
@@ -2956,6 +2956,9 @@ var init_http = __esm({
2956
2956
  if (dryRun) {
2957
2957
  payload.dryRun = true;
2958
2958
  }
2959
+ if (invocation !== void 0) {
2960
+ payload.invocation = invocation;
2961
+ }
2959
2962
  const git = await resolvedGitState();
2960
2963
  if (git && !isEmptyGitState(git)) {
2961
2964
  payload.git = git;
@@ -3751,6 +3754,113 @@ var init_replayInterrupt = __esm({
3751
3754
  }
3752
3755
  });
3753
3756
 
3757
+ // src/replayInvocation.ts
3758
+ function replayEnvironment() {
3759
+ if (readEnv(REPLAY_EXECUTION_TARGET_ENV) === HOSTED_EXECUTION_TARGET) {
3760
+ return "cloud_replay";
3761
+ }
3762
+ if (CI_TRUE_VALUES.has((readEnv(CI_ENV) ?? "").toLowerCase())) {
3763
+ return "ci";
3764
+ }
3765
+ if (CI_PRESENCE_ENV_VARS.some((name) => (readEnv(name) ?? "") !== "")) {
3766
+ return "ci";
3767
+ }
3768
+ return "local";
3769
+ }
3770
+ function flagScalar(value) {
3771
+ if (typeof value === "string") {
3772
+ return value.slice(0, MAX_FLAG_STRING_LENGTH);
3773
+ }
3774
+ if (typeof value === "number") {
3775
+ return Number.isFinite(value) ? value : void 0;
3776
+ }
3777
+ if (typeof value === "boolean" || value === null) {
3778
+ return value;
3779
+ }
3780
+ return void 0;
3781
+ }
3782
+ function flagValue(value) {
3783
+ if (Array.isArray(value)) {
3784
+ const items = value.slice(0, MAX_FLAG_LIST_LENGTH).map(flagScalar);
3785
+ return items.every((item) => item !== void 0) ? items : true;
3786
+ }
3787
+ const scalar = flagScalar(value);
3788
+ return scalar === void 0 ? true : scalar;
3789
+ }
3790
+ function optionFlagName(option) {
3791
+ return OPTION_FLAG_NAMES[option] ?? option.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
3792
+ }
3793
+ function metadataKeys(value) {
3794
+ const keys = Array.isArray(value) ? value.map((pair) => String(pair).split("=")[0]) : typeof value === "object" && value !== null ? Object.keys(value) : void 0;
3795
+ return keys === void 0 ? true : [...new Set(keys)].sort();
3796
+ }
3797
+ function invocationFlags(entries) {
3798
+ const flags = {};
3799
+ const seen = /* @__PURE__ */ new Set();
3800
+ for (const [name, value] of entries) {
3801
+ if (seen.size >= MAX_FLAGS) {
3802
+ break;
3803
+ }
3804
+ if (value === void 0 || seen.has(name) || name.length === 0 || name.length > MAX_FLAG_NAME_LENGTH || SECRET_FLAG_NAME.test(name)) {
3805
+ continue;
3806
+ }
3807
+ flags[name] = flagValue(
3808
+ name === METADATA_FLAG ? metadataKeys(value) : value
3809
+ );
3810
+ seen.add(name);
3811
+ }
3812
+ return flags;
3813
+ }
3814
+ function buildReplayInvocation(entries = []) {
3815
+ return {
3816
+ flags: invocationFlags(entries),
3817
+ sdk: { language: "typescript", version: __version__ },
3818
+ environment: replayEnvironment()
3819
+ };
3820
+ }
3821
+ function safeReplayInvocation(build) {
3822
+ try {
3823
+ return build();
3824
+ } catch {
3825
+ return void 0;
3826
+ }
3827
+ }
3828
+ function cliFlags(options) {
3829
+ return options?.[CLI_FLAGS];
3830
+ }
3831
+ var REPLAY_EXECUTION_TARGET_ENV, HOSTED_EXECUTION_TARGET, CI_ENV, CI_TRUE_VALUES, CI_PRESENCE_ENV_VARS, MAX_FLAGS, MAX_FLAG_NAME_LENGTH, MAX_FLAG_STRING_LENGTH, MAX_FLAG_LIST_LENGTH, SECRET_FLAG_NAME, CLI_FLAGS, METADATA_FLAG, OPTION_FLAG_NAMES;
3832
+ var init_replayInvocation = __esm({
3833
+ "src/replayInvocation.ts"() {
3834
+ "use strict";
3835
+ init_constants();
3836
+ init_readEnv();
3837
+ REPLAY_EXECUTION_TARGET_ENV = "BITFAB_REPLAY_EXECUTION_TARGET";
3838
+ HOSTED_EXECUTION_TARGET = "hosted";
3839
+ CI_ENV = "CI";
3840
+ CI_TRUE_VALUES = /* @__PURE__ */ new Set(["true", "1"]);
3841
+ CI_PRESENCE_ENV_VARS = [
3842
+ "GITHUB_ACTIONS",
3843
+ "GITLAB_CI",
3844
+ "CIRCLECI",
3845
+ "BUILDKITE",
3846
+ "JENKINS_URL",
3847
+ "TF_BUILD"
3848
+ ];
3849
+ MAX_FLAGS = 100;
3850
+ MAX_FLAG_NAME_LENGTH = 100;
3851
+ MAX_FLAG_STRING_LENGTH = 1e3;
3852
+ MAX_FLAG_LIST_LENGTH = 100;
3853
+ SECRET_FLAG_NAME = /key|token|secret|password/i;
3854
+ CLI_FLAGS = /* @__PURE__ */ Symbol("bitfab.replayCliFlags");
3855
+ METADATA_FLAG = "metadata";
3856
+ OPTION_FLAG_NAMES = {
3857
+ maxConcurrency: "concurrency",
3858
+ datasetId: "dataset-ids",
3859
+ datasetIds: "dataset-ids"
3860
+ };
3861
+ }
3862
+ });
3863
+
3754
3864
  // src/selectiveReplay.ts
3755
3865
  function replayNodeKey(node) {
3756
3866
  return JSON.stringify([node.traceFunctionKey, node.spanName]);
@@ -4180,6 +4290,16 @@ function resolveDbBranchSettings(dbBranch) {
4180
4290
  };
4181
4291
  return Object.keys(settings).length === 0 ? void 0 : settings;
4182
4292
  }
4293
+ function explicitReplayOptions(options) {
4294
+ var _a;
4295
+ const explicit = {};
4296
+ for (const name of REPLAY_OPTION_NAMES) {
4297
+ if (options?.[name] !== void 0) {
4298
+ explicit[_a = optionFlagName(name)] ?? (explicit[_a] = options[name]);
4299
+ }
4300
+ }
4301
+ return explicit;
4302
+ }
4183
4303
  function reportReplayProgress(progress) {
4184
4304
  const stderr = typeof process !== "undefined" ? process.stderr : void 0;
4185
4305
  if (!stderr) {
@@ -4691,7 +4811,12 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
4691
4811
  options?.experimentalSelectiveReplay,
4692
4812
  options?.notes,
4693
4813
  options?.metadata,
4694
- options?.dryRun === true
4814
+ options?.dryRun === true,
4815
+ safeReplayInvocation(
4816
+ () => buildReplayInvocation(
4817
+ Object.entries(cliFlags(options) ?? explicitReplayOptions(options))
4818
+ )
4819
+ )
4695
4820
  );
4696
4821
  if (started.items.length === 0) {
4697
4822
  try {
@@ -5083,7 +5208,7 @@ async function writeReplayResultFile(result) {
5083
5208
  }
5084
5209
  }
5085
5210
  }
5086
- var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, RESUME_CONFLICTING_OPTIONS, CARRIED_OVER_ERROR, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError, JUDGE_ASSERTIONS_DEPRECATION_WARNING;
5211
+ var REPLAY_PERSISTENCE_TIMEOUT_MS, MAX_REPLAY_ATTEMPTS, RESUME_CONFLICTING_OPTIONS, CARRIED_OVER_ERROR, REPLAY_OPTION_NAMES, BITFAB_PROGRESS_PREFIX, ReplayError, DbBranchReplayError, JUDGE_ASSERTIONS_DEPRECATION_WARNING;
5087
5212
  var init_replay = __esm({
5088
5213
  "src/replay.ts"() {
5089
5214
  "use strict";
@@ -5096,6 +5221,7 @@ var init_replay = __esm({
5096
5221
  init_replayContext();
5097
5222
  init_replayHeartbeat();
5098
5223
  init_replayInterrupt();
5224
+ init_replayInvocation();
5099
5225
  init_selectiveReplayRuntime();
5100
5226
  init_serialize();
5101
5227
  init_warnOnce();
@@ -5113,6 +5239,37 @@ var init_replay = __esm({
5113
5239
  "experimentalSelectiveReplay"
5114
5240
  ];
5115
5241
  CARRIED_OVER_ERROR = "This item errored in an earlier run of this experiment, before it was resumed.";
5242
+ REPLAY_OPTION_NAMES = [
5243
+ "experimentalSelectiveReplay",
5244
+ "limit",
5245
+ "attempts",
5246
+ "traceIds",
5247
+ "name",
5248
+ "notes",
5249
+ "metadata",
5250
+ "maxConcurrency",
5251
+ "codeChangeDescription",
5252
+ "codeChangeFiles",
5253
+ "mock",
5254
+ "mockOverride",
5255
+ "dbBranch",
5256
+ "experimentGroupId",
5257
+ "datasetId",
5258
+ "datasetIds",
5259
+ "graderIds",
5260
+ "onlyWithAssertions",
5261
+ "skipAssertionJudging",
5262
+ "judgeAssertions",
5263
+ "adaptInputs",
5264
+ "dryRun",
5265
+ "onItemFinish",
5266
+ "onProgress",
5267
+ "onItemStart",
5268
+ "onExperimentStart",
5269
+ "onInterrupt",
5270
+ "resume",
5271
+ "force"
5272
+ ];
5116
5273
  BITFAB_PROGRESS_PREFIX = "@@bitfab:progress ";
5117
5274
  ReplayError = class extends BitfabError {
5118
5275
  constructor(message, items, experimentId, experimentUrl, cause) {
@@ -6889,9 +7046,34 @@ var GradersClient = class {
6889
7046
  init_http();
6890
7047
 
6891
7048
  // src/labels.ts
7049
+ init_errors();
6892
7050
  init_http();
6893
7051
  var LABELS_PATH = "/api/sdk/traces/labels";
6894
7052
  var HUMAN_LABELS_PATH = "/api/sdk/traces/labels/human";
7053
+ function assertEveryVerdictNamesAnAssertion(updates) {
7054
+ const unscoped = updates.filter(
7055
+ (update) => !("archive" in update && update.archive === true) && (typeof update.assertionId !== "string" || update.assertionId === "")
7056
+ );
7057
+ if (unscoped.length > 0) {
7058
+ const targets = unscoped.map(
7059
+ (update) => update.traceId ?? update.originalTraceId
7060
+ );
7061
+ throw new BitfabError(
7062
+ `Agent verdicts must name an assertion: ${targets.join(", ")}. Pass the assertionId of the assertion each verdict scores to labels.save, saveAll, and skip. Only archive may omit it, to clear an old whole-trace verdict.`
7063
+ );
7064
+ }
7065
+ }
7066
+ function assertEveryHumanVerdictNamesAnAssertion(updates) {
7067
+ const unscoped = updates.filter(
7068
+ (update) => typeof update.assertionId !== "string" || update.assertionId === ""
7069
+ );
7070
+ if (unscoped.length > 0) {
7071
+ const targets = unscoped.map((update) => update.traceId);
7072
+ throw new BitfabError(
7073
+ `Human verdicts must name an assertion: ${targets.join(", ")}. Pass the assertionId of the assertion each verdict scores to labels.saveHuman and saveHumanAll.`
7074
+ );
7075
+ }
7076
+ }
6895
7077
  function labelEvidencePath(traceId, assertionId) {
6896
7078
  return `/api/sdk/traces/${encodeURIComponent(traceId)}/assertions/${encodeURIComponent(assertionId)}/evidence`;
6897
7079
  }
@@ -6904,6 +7086,7 @@ var LabelsClient = class {
6904
7086
  return outcome;
6905
7087
  }
6906
7088
  async saveAll(updates, experimentId) {
7089
+ assertEveryVerdictNamesAnAssertion(updates);
6907
7090
  const response = await this.httpClient.request(
6908
7091
  LABELS_PATH,
6909
7092
  {
@@ -6913,11 +7096,9 @@ var LabelsClient = class {
6913
7096
  );
6914
7097
  return response.labels;
6915
7098
  }
6916
- /** Withhold a verdict for a trace or replay attempt whose check did not run. */
6917
7099
  async skip(target, experimentId) {
6918
7100
  return this.save({ ...target, skip: true }, experimentId);
6919
7101
  }
6920
- /** Clear a previous verdict for a trace, replay attempt, or assertion. */
6921
7102
  async archive(target, experimentId) {
6922
7103
  return this.save({ ...target, archive: true }, experimentId);
6923
7104
  }
@@ -6926,6 +7107,7 @@ var LabelsClient = class {
6926
7107
  return outcome;
6927
7108
  }
6928
7109
  async saveHumanAll(updates) {
7110
+ assertEveryHumanVerdictNamesAnAssertion(updates);
6929
7111
  const response = await this.httpClient.request(HUMAN_LABELS_PATH, { labels: updates });
6930
7112
  return response.labels;
6931
7113
  }
@@ -11963,6 +12145,7 @@ init_replay();
11963
12145
  init_errors();
11964
12146
  init_replay();
11965
12147
  init_replayInterrupt();
12148
+ init_replayInvocation();
11966
12149
  init_warnOnce();
11967
12150
  function defineReplayRegistry(registry) {
11968
12151
  validateReplayRegistry(registry);