bitfab 0.54.0 → 0.54.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/index.d.cts CHANGED
@@ -841,6 +841,7 @@ type TraceAssertion = {
841
841
  id: string;
842
842
  traceId: string;
843
843
  assertion: string;
844
+ humanNote: string | null;
844
845
  category_assertion_id: string | null;
845
846
  category: AssertionCategorySummary | null;
846
847
  passCriteria: string | null;
@@ -3378,7 +3379,7 @@ interface CommitRef {
3378
3379
  /**
3379
3380
  * SDK version from package.json (injected at build time)
3380
3381
  */
3381
- declare const __version__ = "0.54.0";
3382
+ declare const __version__ = "0.54.2";
3382
3383
 
3383
3384
  /**
3384
3385
  * Constants for the Bitfab SDK.
package/dist/index.d.ts CHANGED
@@ -841,6 +841,7 @@ type TraceAssertion = {
841
841
  id: string;
842
842
  traceId: string;
843
843
  assertion: string;
844
+ humanNote: string | null;
844
845
  category_assertion_id: string | null;
845
846
  category: AssertionCategorySummary | null;
846
847
  passCriteria: string | null;
@@ -3378,7 +3379,7 @@ interface CommitRef {
3378
3379
  /**
3379
3380
  * SDK version from package.json (injected at build time)
3380
3381
  */
3381
- declare const __version__ = "0.54.0";
3382
+ declare const __version__ = "0.54.2";
3382
3383
 
3383
3384
  /**
3384
3385
  * Constants for the Bitfab SDK.
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  getCurrentTrace,
30
30
  reseedFromRegistry,
31
31
  seedFromRegistry
32
- } from "./chunk-JAXMD6AP.js";
32
+ } from "./chunk-SMNXZVSZ.js";
33
33
  import "./chunk-EGWJYCNT.js";
34
34
  import {
35
35
  BITFAB_PROGRESS_PREFIX,
@@ -38,7 +38,7 @@ import {
38
38
  ReplayError,
39
39
  reportReplayProgress,
40
40
  serializeReplayResult
41
- } from "./chunk-O2OJIGL3.js";
41
+ } from "./chunk-YGVEPWC5.js";
42
42
  import {
43
43
  BitfabError,
44
44
  DEFAULT_SERVICE_URL,
@@ -46,7 +46,7 @@ import {
46
46
  MixedTracingError,
47
47
  __version__,
48
48
  flushTraces
49
- } from "./chunk-SEHWHFUY.js";
49
+ } from "./chunk-GMHABKGI.js";
50
50
  import "./chunk-VCRFFCLY.js";
51
51
  export {
52
52
  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.54.0";
100
+ __version__ = "0.54.2";
101
101
  __packageName__ = "bitfab";
102
102
  }
103
103
  });
@@ -241,6 +241,206 @@ var init_errors = __esm({
241
241
  }
242
242
  });
243
243
 
244
+ // src/gitCommand.ts
245
+ function isUnrefable(value) {
246
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
247
+ }
248
+ function unrefStream(stream) {
249
+ if (isUnrefable(stream)) {
250
+ stream.unref();
251
+ }
252
+ }
253
+ function terminate(child) {
254
+ if (child.pid && process.platform !== "win32") {
255
+ try {
256
+ process.kill(-child.pid, "SIGTERM");
257
+ return;
258
+ } catch {
259
+ child.kill("SIGTERM");
260
+ return;
261
+ }
262
+ }
263
+ child.kill("SIGTERM");
264
+ }
265
+ async function gitRunner(options) {
266
+ let spawn;
267
+ try {
268
+ ;
269
+ ({ spawn } = await import("child_process"));
270
+ } catch {
271
+ return null;
272
+ }
273
+ return (dir, args, env) => new Promise((resolve) => {
274
+ let child;
275
+ try {
276
+ child = spawn("git", args, {
277
+ cwd: dir,
278
+ detached: process.platform !== "win32",
279
+ stdio: ["ignore", "pipe", "pipe"],
280
+ ...env ? { env: { ...process.env, ...env } } : {}
281
+ });
282
+ } catch {
283
+ resolve(null);
284
+ return;
285
+ }
286
+ const chunks = [];
287
+ let size = 0;
288
+ let overflow = false;
289
+ let exitCode = null;
290
+ let done = false;
291
+ const timers = [];
292
+ const schedule = (callback, ms) => {
293
+ const timer = setTimeout(callback, ms);
294
+ if (!options.keepProcessAlive) {
295
+ timer.unref();
296
+ }
297
+ timers.push(timer);
298
+ };
299
+ const finish = () => {
300
+ if (done) {
301
+ return;
302
+ }
303
+ done = true;
304
+ for (const timer of timers) {
305
+ clearTimeout(timer);
306
+ }
307
+ child.stdout?.destroy();
308
+ child.stderr?.destroy();
309
+ resolve(
310
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
311
+ );
312
+ };
313
+ child.stdout?.on("data", (chunk) => {
314
+ size += chunk.length;
315
+ if (size > options.maxBuffer) {
316
+ overflow = true;
317
+ terminate(child);
318
+ return;
319
+ }
320
+ chunks.push(chunk);
321
+ });
322
+ child.stderr?.resume();
323
+ child.on("error", () => {
324
+ exitCode = null;
325
+ finish();
326
+ });
327
+ child.on("exit", (code) => {
328
+ exitCode = code;
329
+ schedule(finish, EXIT_GRACE_MS);
330
+ });
331
+ child.on("close", (code) => {
332
+ exitCode = code ?? exitCode;
333
+ finish();
334
+ });
335
+ schedule(() => terminate(child), options.timeoutMs);
336
+ if (!options.keepProcessAlive) {
337
+ child.unref();
338
+ unrefStream(child.stdout);
339
+ unrefStream(child.stderr);
340
+ }
341
+ });
342
+ }
343
+ var EXIT_GRACE_MS;
344
+ var init_gitCommand = __esm({
345
+ "src/gitCommand.ts"() {
346
+ "use strict";
347
+ EXIT_GRACE_MS = 500;
348
+ }
349
+ });
350
+
351
+ // src/gitState.ts
352
+ function sha(value) {
353
+ const trimmed = value?.trim();
354
+ return trimmed && SHA_PATTERN.test(trimmed) ? trimmed : null;
355
+ }
356
+ function text(value) {
357
+ const trimmed = value?.trim();
358
+ return trimmed ? trimmed : null;
359
+ }
360
+ function isEmptyGitState(state) {
361
+ return Object.values(state).every((value) => value === null);
362
+ }
363
+ async function resolveGitState(cwd) {
364
+ const git = await gitRunner({
365
+ timeoutMs: GIT_TIMEOUT_MS,
366
+ maxBuffer: GIT_MAX_BUFFER,
367
+ keepProcessAlive: true
368
+ });
369
+ if (!git) {
370
+ return null;
371
+ }
372
+ const run = async (args, env) => (await git(cwd, args, env))?.trim() ?? null;
373
+ const [refs, email, branch] = await Promise.all([
374
+ run(["rev-parse", "--show-toplevel", "HEAD", "HEAD^{tree}"]),
375
+ run(["config", "user.email"]),
376
+ run(["symbolic-ref", "--short", "-q", "HEAD"])
377
+ ]);
378
+ const [root, commitSha, baseSha] = (refs ?? "").split("\n");
379
+ if (!root) {
380
+ return null;
381
+ }
382
+ const state = {
383
+ githubEmail: text(email),
384
+ branch: text(branch),
385
+ commitSha: sha(commitSha),
386
+ baseSha: sha(baseSha),
387
+ experimentSha: await resolveWorkingTreeSha(run, root.trim())
388
+ };
389
+ return isEmptyGitState(state) ? null : state;
390
+ }
391
+ async function resolveWorkingTreeSha(run, root) {
392
+ let indexPath;
393
+ let cleanup;
394
+ try {
395
+ const { mkdtemp, rm } = await import("fs/promises");
396
+ const { join } = await import("path");
397
+ const { tmpdir } = await import("os");
398
+ const dir = await mkdtemp(join(tmpdir(), "bitfab-git-"));
399
+ indexPath = join(dir, "index");
400
+ cleanup = () => rm(dir, { recursive: true, force: true });
401
+ } catch {
402
+ return null;
403
+ }
404
+ try {
405
+ const env = { GIT_INDEX_FILE: indexPath };
406
+ if (await run(["read-tree", "HEAD"], env) === null) {
407
+ return null;
408
+ }
409
+ if (await run(["add", "-A", "--", root], env) === null) {
410
+ return null;
411
+ }
412
+ return sha(await run(["write-tree"], env));
413
+ } catch {
414
+ return null;
415
+ } finally {
416
+ await cleanup().catch(() => {
417
+ });
418
+ }
419
+ }
420
+ function resolvedGitState() {
421
+ if (typeof process === "undefined" || process.env?.[DISABLE_ENV]) {
422
+ return Promise.resolve(null);
423
+ }
424
+ let cwd;
425
+ try {
426
+ cwd = process.cwd?.() ?? ".";
427
+ } catch {
428
+ return Promise.resolve(null);
429
+ }
430
+ return resolveGitState(cwd).catch(() => null);
431
+ }
432
+ var GIT_TIMEOUT_MS, GIT_MAX_BUFFER, DISABLE_ENV, SHA_PATTERN;
433
+ var init_gitState = __esm({
434
+ "src/gitState.ts"() {
435
+ "use strict";
436
+ init_gitCommand();
437
+ GIT_TIMEOUT_MS = 3e4;
438
+ GIT_MAX_BUFFER = 1024 * 1024;
439
+ DISABLE_ENV = "BITFAB_DISABLE_GIT_STATE";
440
+ SHA_PATTERN = /^[0-9a-f]{40}$/;
441
+ }
442
+ });
443
+
244
444
  // src/replayContext.ts
245
445
  function getReplayContext() {
246
446
  return replayContextStorage?.getStore() ?? null;
@@ -1962,6 +2162,7 @@ var init_http = __esm({
1962
2162
  init_compress();
1963
2163
  init_constants();
1964
2164
  init_errors();
2165
+ init_gitState();
1965
2166
  init_replayContext();
1966
2167
  init_serializePayload();
1967
2168
  init_simulationPlan();
@@ -2573,6 +2774,10 @@ var init_http = __esm({
2573
2774
  if (onlyWithAssertions) {
2574
2775
  payload.onlyWithAssertions = true;
2575
2776
  }
2777
+ const git = await resolvedGitState();
2778
+ if (git && !isEmptyGitState(git)) {
2779
+ payload.git = git;
2780
+ }
2576
2781
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
2577
2782
  return this.request("/api/sdk/replay/start", payload, {
2578
2783
  timeout
@@ -2920,112 +3125,6 @@ var init_randomUuid = __esm({
2920
3125
  }
2921
3126
  });
2922
3127
 
2923
- // src/gitCommand.ts
2924
- function isUnrefable(value) {
2925
- return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2926
- }
2927
- function unrefStream(stream) {
2928
- if (isUnrefable(stream)) {
2929
- stream.unref();
2930
- }
2931
- }
2932
- function terminate(child) {
2933
- if (child.pid && process.platform !== "win32") {
2934
- try {
2935
- process.kill(-child.pid, "SIGTERM");
2936
- return;
2937
- } catch {
2938
- child.kill("SIGTERM");
2939
- return;
2940
- }
2941
- }
2942
- child.kill("SIGTERM");
2943
- }
2944
- async function gitRunner(options) {
2945
- let spawn;
2946
- try {
2947
- ;
2948
- ({ spawn } = await import("child_process"));
2949
- } catch {
2950
- return null;
2951
- }
2952
- return (dir, args) => new Promise((resolve) => {
2953
- let child;
2954
- try {
2955
- child = spawn("git", args, {
2956
- cwd: dir,
2957
- detached: process.platform !== "win32",
2958
- stdio: ["ignore", "pipe", "pipe"]
2959
- });
2960
- } catch {
2961
- resolve(null);
2962
- return;
2963
- }
2964
- const chunks = [];
2965
- let size = 0;
2966
- let overflow = false;
2967
- let exitCode = null;
2968
- let done = false;
2969
- const timers = [];
2970
- const schedule = (callback, ms) => {
2971
- const timer = setTimeout(callback, ms);
2972
- if (!options.keepProcessAlive) {
2973
- timer.unref();
2974
- }
2975
- timers.push(timer);
2976
- };
2977
- const finish = () => {
2978
- if (done) {
2979
- return;
2980
- }
2981
- done = true;
2982
- for (const timer of timers) {
2983
- clearTimeout(timer);
2984
- }
2985
- child.stdout?.destroy();
2986
- child.stderr?.destroy();
2987
- resolve(
2988
- exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2989
- );
2990
- };
2991
- child.stdout?.on("data", (chunk) => {
2992
- size += chunk.length;
2993
- if (size > options.maxBuffer) {
2994
- overflow = true;
2995
- terminate(child);
2996
- return;
2997
- }
2998
- chunks.push(chunk);
2999
- });
3000
- child.stderr?.resume();
3001
- child.on("error", () => {
3002
- exitCode = null;
3003
- finish();
3004
- });
3005
- child.on("exit", (code) => {
3006
- exitCode = code;
3007
- schedule(finish, EXIT_GRACE_MS);
3008
- });
3009
- child.on("close", (code) => {
3010
- exitCode = code ?? exitCode;
3011
- finish();
3012
- });
3013
- schedule(() => terminate(child), options.timeoutMs);
3014
- if (!options.keepProcessAlive) {
3015
- child.unref();
3016
- unrefStream(child.stdout);
3017
- unrefStream(child.stderr);
3018
- }
3019
- });
3020
- }
3021
- var EXIT_GRACE_MS;
3022
- var init_gitCommand = __esm({
3023
- "src/gitCommand.ts"() {
3024
- "use strict";
3025
- EXIT_GRACE_MS = 500;
3026
- }
3027
- });
3028
-
3029
3128
  // src/mockOverride.ts
3030
3129
  function resolveMockValue(value, ctx) {
3031
3130
  return typeof value === "function" ? value(ctx) : value;
@@ -5334,9 +5433,9 @@ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunc
5334
5433
  init_gitCommand();
5335
5434
  init_readEnv();
5336
5435
  var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
5337
- var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
5338
- var GIT_TIMEOUT_MS = 2e3;
5339
- var GIT_MAX_BUFFER = 1024 * 1024;
5436
+ var DISABLE_ENV2 = "BITFAB_DISABLE_COMMIT_REF";
5437
+ var GIT_TIMEOUT_MS2 = 2e3;
5438
+ var GIT_MAX_BUFFER2 = 1024 * 1024;
5340
5439
  var VERCEL_PROVIDER_HOSTS = {
5341
5440
  github: "github.com",
5342
5441
  gitlab: "gitlab.com",
@@ -5392,9 +5491,9 @@ var PLATFORM_ENVS = [
5392
5491
  ];
5393
5492
  var COMMIT_REF_ENV_NAMES = [
5394
5493
  EXPLICIT_SHA_ENV,
5395
- DISABLE_ENV,
5494
+ DISABLE_ENV2,
5396
5495
  ...PLATFORM_ENVS.flatMap(
5397
- ([sha, branch]) => branch === null ? [sha] : [sha, branch]
5496
+ ([sha2, branch]) => branch === null ? [sha2] : [sha2, branch]
5398
5497
  ),
5399
5498
  "GITHUB_SERVER_URL",
5400
5499
  "GITHUB_REPOSITORY",
@@ -5439,7 +5538,7 @@ function normalizeRemote(raw) {
5439
5538
  }
5440
5539
  function resolveCommitRefFromEnv(env) {
5441
5540
  const explicit = read(env, EXPLICIT_SHA_ENV);
5442
- const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
5541
+ const platform = PLATFORM_ENVS.find(([sha2]) => read(env, sha2) !== null);
5443
5542
  if (!platform) {
5444
5543
  if (explicit === null) {
5445
5544
  return null;
@@ -5463,16 +5562,16 @@ function resolveCommitRefFromEnv(env) {
5463
5562
  }
5464
5563
  async function resolveCommitRefFromGit(cwd) {
5465
5564
  const git = await gitRunner({
5466
- timeoutMs: GIT_TIMEOUT_MS,
5467
- maxBuffer: GIT_MAX_BUFFER,
5565
+ timeoutMs: GIT_TIMEOUT_MS2,
5566
+ maxBuffer: GIT_MAX_BUFFER2,
5468
5567
  keepProcessAlive: false
5469
5568
  });
5470
5569
  if (!git) {
5471
5570
  return null;
5472
5571
  }
5473
5572
  const run = async (args) => (await git(cwd, args))?.trim() ?? null;
5474
- const sha = await run(["rev-parse", "HEAD"]);
5475
- if (!sha) {
5573
+ const sha2 = await run(["rev-parse", "HEAD"]);
5574
+ if (!sha2) {
5476
5575
  return null;
5477
5576
  }
5478
5577
  const [branch, status, remote, roots] = await Promise.all([
@@ -5482,7 +5581,7 @@ async function resolveCommitRefFromGit(cwd) {
5482
5581
  run(["rev-list", "--max-parents=0", "HEAD"])
5483
5582
  ]);
5484
5583
  return {
5485
- sha,
5584
+ sha: sha2,
5486
5585
  branch: branch || null,
5487
5586
  dirty: status === null ? null : status.length > 0,
5488
5587
  remote: normalizeRemote(remote),
@@ -5506,7 +5605,7 @@ function startCommitRefResolution() {
5506
5605
  if (resolved || gitStarted) {
5507
5606
  return;
5508
5607
  }
5509
- if (read(readEnv, DISABLE_ENV) !== null) {
5608
+ if (read(readEnv, DISABLE_ENV2) !== null) {
5510
5609
  resolved = true;
5511
5610
  return;
5512
5611
  }
@@ -7087,14 +7186,14 @@ function modelLabel(model) {
7087
7186
  }
7088
7187
  function summarizeGenerate(result, model) {
7089
7188
  const content = Array.isArray(result.content) ? result.content : [];
7090
- const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7189
+ const text2 = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7091
7190
  const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
7092
7191
  toolCallId: p.toolCallId,
7093
7192
  toolName: p.toolName,
7094
7193
  input: p.input ?? p.args
7095
7194
  }));
7096
7195
  const summary = {
7097
- text,
7196
+ text: text2,
7098
7197
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7099
7198
  usage: result.usage,
7100
7199
  finishReason: result.finishReason
@@ -7106,7 +7205,7 @@ function summarizeGenerate(result, model) {
7106
7205
  }
7107
7206
  function accumulateStream(source, onComplete, model) {
7108
7207
  const reader = source.getReader();
7109
- let text = "";
7208
+ let text2 = "";
7110
7209
  const toolCalls = [];
7111
7210
  let usage;
7112
7211
  let finishReason;
@@ -7128,7 +7227,7 @@ function accumulateStream(source, onComplete, model) {
7128
7227
  }
7129
7228
  }
7130
7229
  onComplete({
7131
- text,
7230
+ text: text2,
7132
7231
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7133
7232
  usage,
7134
7233
  finishReason,
@@ -7173,7 +7272,7 @@ function accumulateStream(source, onComplete, model) {
7173
7272
  }
7174
7273
  try {
7175
7274
  if (part?.type === "text-delta") {
7176
- text += part.delta ?? part.textDelta ?? "";
7275
+ text2 += part.delta ?? part.textDelta ?? "";
7177
7276
  } else if (part?.type === "tool-call") {
7178
7277
  toolCalls.push({
7179
7278
  toolCallId: part.toolCallId,
@@ -9662,7 +9761,7 @@ async function settle(value) {
9662
9761
  }
9663
9762
  async function aiSdk(result) {
9664
9763
  const r = result ?? {};
9665
- const [text, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9764
+ const [text2, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9666
9765
  settle(r.text),
9667
9766
  settle(r.usage),
9668
9767
  settle(r.totalUsage),
@@ -9671,7 +9770,7 @@ async function aiSdk(result) {
9671
9770
  settle(r.toolResults)
9672
9771
  ]);
9673
9772
  return {
9674
- text,
9773
+ text: text2,
9675
9774
  usage: totalUsage ?? usage,
9676
9775
  finishReason,
9677
9776
  toolCalls,