bitfab 0.52.3 → 0.52.5

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 (35) hide show
  1. package/README.md +2 -0
  2. package/dist/{chunk-JPFJ5YSK.js → chunk-3D7FNJ5R.js} +14 -2
  3. package/dist/{chunk-JPFJ5YSK.js.map → chunk-3D7FNJ5R.js.map} +1 -1
  4. package/dist/chunk-3QXNM62Y.js +747 -0
  5. package/dist/chunk-3QXNM62Y.js.map +1 -0
  6. package/dist/{chunk-NZGYJWHY.js → chunk-6DRFQJ75.js} +111 -13
  7. package/dist/chunk-6DRFQJ75.js.map +1 -0
  8. package/dist/{chunk-XRSOWDOP.js → chunk-CAE7HE4C.js} +15 -2
  9. package/dist/{chunk-XRSOWDOP.js.map → chunk-CAE7HE4C.js.map} +1 -1
  10. package/dist/{chunk-EAET3MSX.js → chunk-EMRHO6YW.js} +291 -21
  11. package/dist/chunk-EMRHO6YW.js.map +1 -0
  12. package/dist/{http-HSNLZMNZ.js → http-Q6UEKZRF.js} +2 -2
  13. package/dist/{http-W66ZE5TL.js → http-UQT6QVBC.js} +2 -2
  14. package/dist/index.cjs +444 -57
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +44 -2
  17. package/dist/index.d.ts +44 -2
  18. package/dist/index.js +5 -3
  19. package/dist/node.cjs +444 -57
  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 +5 -3
  24. package/dist/node.js.map +1 -1
  25. package/dist/{replay-QMA2K5M4.js → replay-UVSZFZW7.js} +5 -3
  26. package/dist/replayCli.js +18 -687
  27. package/dist/replayCli.js.map +1 -1
  28. package/dist/seedCli.js +30 -0
  29. package/dist/seedCli.js.map +1 -0
  30. package/package.json +3 -2
  31. package/dist/chunk-EAET3MSX.js.map +0 -1
  32. package/dist/chunk-NZGYJWHY.js.map +0 -1
  33. /package/dist/{http-HSNLZMNZ.js.map → http-Q6UEKZRF.js.map} +0 -0
  34. /package/dist/{http-W66ZE5TL.js.map → http-UQT6QVBC.js.map} +0 -0
  35. /package/dist/{replay-QMA2K5M4.js.map → replay-UVSZFZW7.js.map} +0 -0
@@ -8,13 +8,15 @@ import {
8
8
  } from "./chunk-ZUD7OFYB.js";
9
9
  import {
10
10
  NO_MOCK_OVERRIDE,
11
+ deserializeInputs,
11
12
  deserializeValue,
13
+ gitRunner,
12
14
  randomUuid,
13
15
  resolveMockValue,
14
16
  serializeValue,
15
17
  toJsonSafe,
16
18
  toJsonSafeReport
17
- } from "./chunk-NZGYJWHY.js";
19
+ } from "./chunk-6DRFQJ75.js";
18
20
  import {
19
21
  BitfabError,
20
22
  DEFAULT_SERVICE_URL,
@@ -22,10 +24,11 @@ import {
22
24
  MixedTracingError,
23
25
  callerTraceMetadata,
24
26
  getReplayContext,
27
+ readEnv,
25
28
  recordCallerTraceMetadata,
26
29
  retireTraceMetadata,
27
30
  warnOnce
28
- } from "./chunk-XRSOWDOP.js";
31
+ } from "./chunk-CAE7HE4C.js";
29
32
  import {
30
33
  __privateAdd,
31
34
  __privateGet,
@@ -1016,24 +1019,237 @@ function mixedTracingError(enteredApi, entered, enclosing, traceFunctionKey) {
1016
1019
  `opt-in and opt-out tracing can't be mixed in one call stack: ${enteredApi} (${entered})${subject} was entered inside a ${SURFACE_API[enclosing]} call (${enclosing}). ${MIXED_SURFACE_REMEDY[entered]}`
1017
1020
  );
1018
1021
  }
1019
- function assertSurfacesCompatible(requested, resolved, parentSurface, traceFunctionKey) {
1022
+ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunctionKey) {
1020
1023
  if (requested === "inherit" || requested === "neutral") {
1021
1024
  return;
1022
1025
  }
1023
- if (resolved === void 0 || parentSurface === void 0) {
1026
+ if (resolved2 === void 0 || parentSurface === void 0) {
1024
1027
  return;
1025
1028
  }
1026
- if (parentSurface === resolved) {
1029
+ if (parentSurface === resolved2) {
1027
1030
  return;
1028
1031
  }
1029
1032
  throw mixedTracingError(
1030
- SURFACE_API[resolved],
1031
- resolved,
1033
+ SURFACE_API[resolved2],
1034
+ resolved2,
1032
1035
  parentSurface,
1033
1036
  traceFunctionKey
1034
1037
  );
1035
1038
  }
1036
1039
 
1040
+ // src/commitRef.ts
1041
+ var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
1042
+ var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
1043
+ var GIT_TIMEOUT_MS = 2e3;
1044
+ var GIT_MAX_BUFFER = 1024 * 1024;
1045
+ var VERCEL_PROVIDER_HOSTS = {
1046
+ github: "github.com",
1047
+ gitlab: "gitlab.com",
1048
+ bitbucket: "bitbucket.org"
1049
+ };
1050
+ function read(env, name) {
1051
+ if (name === null) {
1052
+ return null;
1053
+ }
1054
+ const value = env(name)?.trim();
1055
+ return value ? value : null;
1056
+ }
1057
+ function remoteFrom(...names) {
1058
+ return (env) => {
1059
+ const parts = names.map((name) => read(env, name));
1060
+ if (parts.some((part) => part === null)) {
1061
+ return null;
1062
+ }
1063
+ return normalizeRemote(parts.join("/"));
1064
+ };
1065
+ }
1066
+ function vercelRemote(env) {
1067
+ const provider = read(env, "VERCEL_GIT_PROVIDER")?.toLowerCase() ?? "";
1068
+ const host = VERCEL_PROVIDER_HOSTS[provider];
1069
+ const owner = read(env, "VERCEL_GIT_REPO_OWNER");
1070
+ const slug = read(env, "VERCEL_GIT_REPO_SLUG");
1071
+ if (!host || !owner || !slug) {
1072
+ return null;
1073
+ }
1074
+ return `${host}/${owner}/${slug}`;
1075
+ }
1076
+ function noRemote() {
1077
+ return null;
1078
+ }
1079
+ var PLATFORM_ENVS = [
1080
+ ["VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF", vercelRemote],
1081
+ [
1082
+ "GITHUB_SHA",
1083
+ "GITHUB_REF_NAME",
1084
+ remoteFrom("GITHUB_SERVER_URL", "GITHUB_REPOSITORY")
1085
+ ],
1086
+ ["RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH", noRemote],
1087
+ ["RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH", noRemote],
1088
+ ["SOURCE_VERSION", null, noRemote],
1089
+ ["CF_PAGES_COMMIT_SHA", "CF_PAGES_BRANCH", noRemote],
1090
+ ["CI_COMMIT_SHA", "CI_COMMIT_REF_NAME", remoteFrom("CI_REPOSITORY_URL")],
1091
+ [
1092
+ "BUILD_SOURCEVERSION",
1093
+ "BUILD_SOURCEBRANCHNAME",
1094
+ remoteFrom("BUILD_REPOSITORY_URI")
1095
+ ],
1096
+ ["CIRCLE_SHA1", "CIRCLE_BRANCH", remoteFrom("CIRCLE_REPOSITORY_URL")]
1097
+ ];
1098
+ var COMMIT_REF_ENV_NAMES = [
1099
+ EXPLICIT_SHA_ENV,
1100
+ DISABLE_ENV,
1101
+ ...PLATFORM_ENVS.flatMap(
1102
+ ([sha, branch]) => branch === null ? [sha] : [sha, branch]
1103
+ ),
1104
+ "GITHUB_SERVER_URL",
1105
+ "GITHUB_REPOSITORY",
1106
+ "CI_REPOSITORY_URL",
1107
+ "BUILD_REPOSITORY_URI",
1108
+ "CIRCLE_REPOSITORY_URL",
1109
+ "VERCEL_GIT_PROVIDER",
1110
+ "VERCEL_GIT_REPO_OWNER",
1111
+ "VERCEL_GIT_REPO_SLUG"
1112
+ ];
1113
+ function normalizeRemote(raw) {
1114
+ const value = raw?.trim();
1115
+ if (!value) {
1116
+ return null;
1117
+ }
1118
+ let host = "";
1119
+ let path = value;
1120
+ if (value.includes("://")) {
1121
+ try {
1122
+ const parsed = new URL(value);
1123
+ host = parsed.hostname;
1124
+ path = parsed.pathname;
1125
+ } catch {
1126
+ return null;
1127
+ }
1128
+ } else {
1129
+ const separator = value.indexOf(":");
1130
+ if (separator !== -1) {
1131
+ const head = value.slice(0, separator);
1132
+ host = head.slice(head.lastIndexOf("@") + 1);
1133
+ path = value.slice(separator + 1);
1134
+ }
1135
+ }
1136
+ path = path.replace(/^\/+|\/+$/g, "");
1137
+ if (path.endsWith(".git")) {
1138
+ path = path.slice(0, -".git".length).replace(/\/+$/, "");
1139
+ }
1140
+ if (!host) {
1141
+ return path || null;
1142
+ }
1143
+ return path ? `${host}/${path}` : host;
1144
+ }
1145
+ function resolveCommitRefFromEnv(env) {
1146
+ const explicit = read(env, EXPLICIT_SHA_ENV);
1147
+ const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
1148
+ if (!platform) {
1149
+ if (explicit === null) {
1150
+ return null;
1151
+ }
1152
+ return {
1153
+ sha: explicit,
1154
+ branch: null,
1155
+ dirty: null,
1156
+ remote: null,
1157
+ rootSha: null
1158
+ };
1159
+ }
1160
+ const [shaEnv, branchEnv, readRemote] = platform;
1161
+ return {
1162
+ sha: explicit ?? read(env, shaEnv),
1163
+ branch: read(env, branchEnv),
1164
+ dirty: null,
1165
+ remote: readRemote(env),
1166
+ rootSha: null
1167
+ };
1168
+ }
1169
+ async function resolveCommitRefFromGit(cwd) {
1170
+ const git = await gitRunner({
1171
+ timeoutMs: GIT_TIMEOUT_MS,
1172
+ maxBuffer: GIT_MAX_BUFFER,
1173
+ keepProcessAlive: false
1174
+ });
1175
+ if (!git) {
1176
+ return null;
1177
+ }
1178
+ const run = async (args) => (await git(cwd, args))?.trim() ?? null;
1179
+ const sha = await run(["rev-parse", "HEAD"]);
1180
+ if (!sha) {
1181
+ return null;
1182
+ }
1183
+ const [branch, status, remote, roots] = await Promise.all([
1184
+ run(["symbolic-ref", "--short", "-q", "HEAD"]),
1185
+ run(["status", "--porcelain"]),
1186
+ run(["remote", "get-url", "origin"]),
1187
+ run(["rev-list", "--max-parents=0", "HEAD"])
1188
+ ]);
1189
+ return {
1190
+ sha,
1191
+ branch: branch || null,
1192
+ dirty: status === null ? null : status.length > 0,
1193
+ remote: normalizeRemote(remote),
1194
+ rootSha: roots ? roots.split(/\s+/).sort()[0] ?? null : null
1195
+ };
1196
+ }
1197
+ function commitRefWire(ref2) {
1198
+ return {
1199
+ sha: ref2.sha,
1200
+ branch: ref2.branch,
1201
+ dirty: ref2.dirty,
1202
+ remote: ref2.remote,
1203
+ root_sha: ref2.rootSha
1204
+ };
1205
+ }
1206
+ var resolved = false;
1207
+ var ref = null;
1208
+ var gitStarted = false;
1209
+ var settled = Promise.resolve();
1210
+ function startCommitRefResolution() {
1211
+ if (resolved || gitStarted) {
1212
+ return;
1213
+ }
1214
+ if (read(readEnv, DISABLE_ENV) !== null) {
1215
+ resolved = true;
1216
+ return;
1217
+ }
1218
+ const fromEnv = resolveCommitRefFromEnv(readEnv);
1219
+ if (fromEnv) {
1220
+ ref = fromEnv;
1221
+ resolved = true;
1222
+ return;
1223
+ }
1224
+ gitStarted = true;
1225
+ if (typeof process === "undefined") {
1226
+ resolved = true;
1227
+ return;
1228
+ }
1229
+ let cwd;
1230
+ try {
1231
+ cwd = process.cwd?.() ?? ".";
1232
+ } catch {
1233
+ resolved = true;
1234
+ return;
1235
+ }
1236
+ settled = resolveCommitRefFromGit(cwd).then(
1237
+ (fromGit) => {
1238
+ if (!resolved) {
1239
+ ref = fromGit;
1240
+ resolved = true;
1241
+ }
1242
+ },
1243
+ () => {
1244
+ resolved = true;
1245
+ }
1246
+ );
1247
+ }
1248
+ function currentCommitRef() {
1249
+ startCommitRefResolution();
1250
+ return ref;
1251
+ }
1252
+
1037
1253
  // src/datasets.ts
1038
1254
  var DEFAULT_RERUN_TIMEOUT_MS = 9e4;
1039
1255
  var DEFAULT_RERUN_POLL_INTERVAL_MS = 1e3;
@@ -1511,11 +1727,11 @@ var BitfabLangGraphCallbackHandler = class {
1511
1727
  this.invocations.set(invocation.rootRunId, invocation);
1512
1728
  }
1513
1729
  if (!willHide) {
1514
- let resolved = parentSpan;
1515
- while (resolved?.hidden === true) {
1516
- resolved = resolved.parentId ? this.runToSpan.get(resolved.parentId) : void 0;
1730
+ let resolved2 = parentSpan;
1731
+ while (resolved2?.hidden === true) {
1732
+ resolved2 = resolved2.parentId ? this.runToSpan.get(resolved2.parentId) : void 0;
1517
1733
  }
1518
- effectiveParentId = resolved ? resolved.spanId : invocation.activeContext?.spanId ?? null;
1734
+ effectiveParentId = resolved2 ? resolved2.spanId : invocation.activeContext?.spanId ?? null;
1519
1735
  } else {
1520
1736
  effectiveParentId = parentRunId ?? null;
1521
1737
  }
@@ -2947,7 +3163,7 @@ function getCurrentTrace() {
2947
3163
  }
2948
3164
  };
2949
3165
  }
2950
- function readEnv(name) {
3166
+ function readEnv2(name) {
2951
3167
  if (typeof process !== "undefined" && process.env) {
2952
3168
  return process.env[name];
2953
3169
  }
@@ -2994,6 +3210,7 @@ var Bitfab = class {
2994
3210
  validateDbSnapshotConfig(config.dbSnapshot);
2995
3211
  }
2996
3212
  this.dbSnapshot = config.dbSnapshot;
3213
+ startCommitRefResolution();
2997
3214
  this.httpClient = new HttpClient({
2998
3215
  apiKey: () => this.resolveApiKey(),
2999
3216
  serviceUrl: this.serviceUrl,
@@ -3329,7 +3546,7 @@ var Bitfab = class {
3329
3546
  return this.resolvedApiKey;
3330
3547
  }
3331
3548
  const fromConfig = typeof this.apiKeyConfig === "function" ? this.apiKeyConfig() : this.apiKeyConfig;
3332
- const candidate = fromConfig && fromConfig.trim() !== "" ? fromConfig : readEnv("BITFAB_API_KEY");
3549
+ const candidate = fromConfig && fromConfig.trim() !== "" ? fromConfig : readEnv2("BITFAB_API_KEY");
3333
3550
  const key = candidate && candidate.trim() !== "" ? candidate : void 0;
3334
3551
  if (key) {
3335
3552
  this.resolvedApiKey = key;
@@ -4087,15 +4304,15 @@ var Bitfab = class {
4087
4304
  );
4088
4305
  }
4089
4306
  return runWithSpanStack(newStack, async () => {
4090
- const resolved = await resolution;
4091
- if (resolved.matched) {
4307
+ const resolved2 = await resolution;
4308
+ if (resolved2.matched) {
4092
4309
  void sendSpan({
4093
- result: resolved.output,
4310
+ result: resolved2.output,
4094
4311
  mocked: true,
4095
4312
  mockTarget: "output",
4096
4313
  mockSource: "override"
4097
4314
  });
4098
- return resolved.output;
4315
+ return resolved2.output;
4099
4316
  }
4100
4317
  if (shouldMockWithBaseStrategy && !mockSpan) {
4101
4318
  throw new BitfabError(
@@ -4331,6 +4548,10 @@ var Bitfab = class {
4331
4548
  if (params.dbSnapshotRef) {
4332
4549
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
4333
4550
  }
4551
+ const commitRef = currentCommitRef();
4552
+ if (commitRef) {
4553
+ rawTrace.commit_ref = commitRefWire(commitRef);
4554
+ }
4334
4555
  if (params.ingestionType) {
4335
4556
  rawTrace.ingestion_type = params.ingestionType;
4336
4557
  }
@@ -4576,7 +4797,7 @@ var Bitfab = class {
4576
4797
  await runWithSeedContext({ traceId }, async () => target(...args));
4577
4798
  } finally {
4578
4799
  try {
4579
- const { flushTraces: flushTraces2 } = await import("./http-HSNLZMNZ.js");
4800
+ const { flushTraces: flushTraces2 } = await import("./http-Q6UEKZRF.js");
4580
4801
  await flushTraces2(3e4);
4581
4802
  } finally {
4582
4803
  unrecorded = activeTraceStates.delete(traceId);
@@ -4590,6 +4811,36 @@ var Bitfab = class {
4590
4811
  }
4591
4812
  return traceId;
4592
4813
  }
4814
+ async reseedTrace(traceFunctionKey, fn, options) {
4815
+ const source = await this.httpClient.getReseedSource(options.traceId);
4816
+ if (source.traceFunctionKey !== traceFunctionKey) {
4817
+ throw new BitfabError(
4818
+ `Trace ${options.traceId} belongs to '${source.traceFunctionKey}', not '${traceFunctionKey}'.`
4819
+ );
4820
+ }
4821
+ const args = deserializeInputs({
4822
+ input: source.input,
4823
+ input_meta: source.inputMeta
4824
+ });
4825
+ const runTraceId = await this.seedTraceByRunning(
4826
+ traceFunctionKey,
4827
+ fn,
4828
+ {
4829
+ args,
4830
+ metadata: source.metadata,
4831
+ ...source.sessionId === null ? {} : { sessionId: source.sessionId },
4832
+ ...source.name === null ? {} : { name: source.name }
4833
+ }
4834
+ );
4835
+ const adopted = await this.httpClient.reseedTrace(
4836
+ options.traceId,
4837
+ runTraceId
4838
+ );
4839
+ return {
4840
+ traceId: adopted.traceId,
4841
+ previousRunTraceId: adopted.previousRunTraceId
4842
+ };
4843
+ }
4593
4844
  async replay(traceFunctionKey, fn, options) {
4594
4845
  const wrappedKey = fn._bitfabTraceFunctionKey;
4595
4846
  let replayFn = fn;
@@ -4605,7 +4856,7 @@ var Bitfab = class {
4605
4856
  `Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`
4606
4857
  );
4607
4858
  }
4608
- const { replay: doReplay } = await import("./replay-QMA2K5M4.js");
4859
+ const { replay: doReplay } = await import("./replay-UVSZFZW7.js");
4609
4860
  return doReplay(
4610
4861
  this.httpClient,
4611
4862
  this.serviceUrl,
@@ -4841,6 +5092,24 @@ var finalizers = {
4841
5092
  function defineReplayRegistry(registry) {
4842
5093
  return registry;
4843
5094
  }
5095
+ async function reseedFromRegistry(registry, pipeline, traceIds) {
5096
+ const registration = registry[pipeline];
5097
+ if (registration === void 0) {
5098
+ throw new BitfabError(
5099
+ `Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`
5100
+ );
5101
+ }
5102
+ const traceFunctionKey = resolveTraceFunctionKey(registration);
5103
+ const reseeded = [];
5104
+ for (const traceId of traceIds) {
5105
+ reseeded.push(
5106
+ await registration.client.reseedTrace(traceFunctionKey, registration.fn, {
5107
+ traceId
5108
+ })
5109
+ );
5110
+ }
5111
+ return { pipeline, traceFunctionKey, reseeded };
5112
+ }
4844
5113
  async function seedFromRegistry(registry, pipeline, cases, options = {}) {
4845
5114
  const registration = registry[pipeline];
4846
5115
  if (registration === void 0) {
@@ -4871,7 +5140,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
4871
5140
  sessionId: seedCase.sessionId
4872
5141
  })
4873
5142
  );
4874
- const { flushTraces: flushTraces2 } = await import("./http-HSNLZMNZ.js");
5143
+ const { flushTraces: flushTraces2 } = await import("./http-Q6UEKZRF.js");
4875
5144
  await flushTraces2(3e4);
4876
5145
  return { pipeline, traceFunctionKey, traceIds };
4877
5146
  }
@@ -4905,6 +5174,7 @@ export {
4905
5174
  BitfabFunction,
4906
5175
  finalizers,
4907
5176
  defineReplayRegistry,
5177
+ reseedFromRegistry,
4908
5178
  seedFromRegistry
4909
5179
  };
4910
- //# sourceMappingURL=chunk-EAET3MSX.js.map
5180
+ //# sourceMappingURL=chunk-EMRHO6YW.js.map