@bitfab/sdk 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
@@ -20,7 +20,7 @@ import {
20
20
  getCurrentTrace,
21
21
  reseedFromRegistry,
22
22
  seedFromRegistry
23
- } from "./chunk-SOYIEIGU.js";
23
+ } from "./chunk-4ZACHEMR.js";
24
24
  import "./chunk-EGWJYCNT.js";
25
25
  import {
26
26
  BITFAB_PROGRESS_PREFIX,
@@ -29,7 +29,7 @@ import {
29
29
  ReplayError,
30
30
  reportReplayProgress,
31
31
  serializeReplayResult
32
- } from "./chunk-MZ42HQ7N.js";
32
+ } from "./chunk-SPZEKXAE.js";
33
33
  import {
34
34
  BitfabError,
35
35
  DEFAULT_SERVICE_URL,
@@ -37,7 +37,7 @@ import {
37
37
  MixedTracingError,
38
38
  __version__,
39
39
  flushTraces
40
- } from "./chunk-EPWQ43SC.js";
40
+ } from "./chunk-BIEDMC5U.js";
41
41
  import "./chunk-VCRFFCLY.js";
42
42
  export {
43
43
  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.54.0";
91
+ __version__ = "0.54.2";
92
92
  __packageName__ = "@bitfab/sdk";
93
93
  }
94
94
  });
@@ -232,6 +232,206 @@ var init_errors = __esm({
232
232
  }
233
233
  });
234
234
 
235
+ // src/gitCommand.ts
236
+ function isUnrefable(value) {
237
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
238
+ }
239
+ function unrefStream(stream) {
240
+ if (isUnrefable(stream)) {
241
+ stream.unref();
242
+ }
243
+ }
244
+ function terminate(child) {
245
+ if (child.pid && process.platform !== "win32") {
246
+ try {
247
+ process.kill(-child.pid, "SIGTERM");
248
+ return;
249
+ } catch {
250
+ child.kill("SIGTERM");
251
+ return;
252
+ }
253
+ }
254
+ child.kill("SIGTERM");
255
+ }
256
+ async function gitRunner(options) {
257
+ let spawn;
258
+ try {
259
+ ;
260
+ ({ spawn } = await import("child_process"));
261
+ } catch {
262
+ return null;
263
+ }
264
+ return (dir, args, env) => new Promise((resolve) => {
265
+ let child;
266
+ try {
267
+ child = spawn("git", args, {
268
+ cwd: dir,
269
+ detached: process.platform !== "win32",
270
+ stdio: ["ignore", "pipe", "pipe"],
271
+ ...env ? { env: { ...process.env, ...env } } : {}
272
+ });
273
+ } catch {
274
+ resolve(null);
275
+ return;
276
+ }
277
+ const chunks = [];
278
+ let size = 0;
279
+ let overflow = false;
280
+ let exitCode = null;
281
+ let done = false;
282
+ const timers = [];
283
+ const schedule = (callback, ms) => {
284
+ const timer = setTimeout(callback, ms);
285
+ if (!options.keepProcessAlive) {
286
+ timer.unref();
287
+ }
288
+ timers.push(timer);
289
+ };
290
+ const finish = () => {
291
+ if (done) {
292
+ return;
293
+ }
294
+ done = true;
295
+ for (const timer of timers) {
296
+ clearTimeout(timer);
297
+ }
298
+ child.stdout?.destroy();
299
+ child.stderr?.destroy();
300
+ resolve(
301
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
302
+ );
303
+ };
304
+ child.stdout?.on("data", (chunk) => {
305
+ size += chunk.length;
306
+ if (size > options.maxBuffer) {
307
+ overflow = true;
308
+ terminate(child);
309
+ return;
310
+ }
311
+ chunks.push(chunk);
312
+ });
313
+ child.stderr?.resume();
314
+ child.on("error", () => {
315
+ exitCode = null;
316
+ finish();
317
+ });
318
+ child.on("exit", (code) => {
319
+ exitCode = code;
320
+ schedule(finish, EXIT_GRACE_MS);
321
+ });
322
+ child.on("close", (code) => {
323
+ exitCode = code ?? exitCode;
324
+ finish();
325
+ });
326
+ schedule(() => terminate(child), options.timeoutMs);
327
+ if (!options.keepProcessAlive) {
328
+ child.unref();
329
+ unrefStream(child.stdout);
330
+ unrefStream(child.stderr);
331
+ }
332
+ });
333
+ }
334
+ var EXIT_GRACE_MS;
335
+ var init_gitCommand = __esm({
336
+ "src/gitCommand.ts"() {
337
+ "use strict";
338
+ EXIT_GRACE_MS = 500;
339
+ }
340
+ });
341
+
342
+ // src/gitState.ts
343
+ function sha(value) {
344
+ const trimmed = value?.trim();
345
+ return trimmed && SHA_PATTERN.test(trimmed) ? trimmed : null;
346
+ }
347
+ function text(value) {
348
+ const trimmed = value?.trim();
349
+ return trimmed ? trimmed : null;
350
+ }
351
+ function isEmptyGitState(state) {
352
+ return Object.values(state).every((value) => value === null);
353
+ }
354
+ async function resolveGitState(cwd) {
355
+ const git = await gitRunner({
356
+ timeoutMs: GIT_TIMEOUT_MS,
357
+ maxBuffer: GIT_MAX_BUFFER,
358
+ keepProcessAlive: true
359
+ });
360
+ if (!git) {
361
+ return null;
362
+ }
363
+ const run = async (args, env) => (await git(cwd, args, env))?.trim() ?? null;
364
+ const [refs, email, branch] = await Promise.all([
365
+ run(["rev-parse", "--show-toplevel", "HEAD", "HEAD^{tree}"]),
366
+ run(["config", "user.email"]),
367
+ run(["symbolic-ref", "--short", "-q", "HEAD"])
368
+ ]);
369
+ const [root, commitSha, baseSha] = (refs ?? "").split("\n");
370
+ if (!root) {
371
+ return null;
372
+ }
373
+ const state = {
374
+ githubEmail: text(email),
375
+ branch: text(branch),
376
+ commitSha: sha(commitSha),
377
+ baseSha: sha(baseSha),
378
+ experimentSha: await resolveWorkingTreeSha(run, root.trim())
379
+ };
380
+ return isEmptyGitState(state) ? null : state;
381
+ }
382
+ async function resolveWorkingTreeSha(run, root) {
383
+ let indexPath;
384
+ let cleanup;
385
+ try {
386
+ const { mkdtemp, rm } = await import("fs/promises");
387
+ const { join } = await import("path");
388
+ const { tmpdir } = await import("os");
389
+ const dir = await mkdtemp(join(tmpdir(), "bitfab-git-"));
390
+ indexPath = join(dir, "index");
391
+ cleanup = () => rm(dir, { recursive: true, force: true });
392
+ } catch {
393
+ return null;
394
+ }
395
+ try {
396
+ const env = { GIT_INDEX_FILE: indexPath };
397
+ if (await run(["read-tree", "HEAD"], env) === null) {
398
+ return null;
399
+ }
400
+ if (await run(["add", "-A", "--", root], env) === null) {
401
+ return null;
402
+ }
403
+ return sha(await run(["write-tree"], env));
404
+ } catch {
405
+ return null;
406
+ } finally {
407
+ await cleanup().catch(() => {
408
+ });
409
+ }
410
+ }
411
+ function resolvedGitState() {
412
+ if (typeof process === "undefined" || process.env?.[DISABLE_ENV]) {
413
+ return Promise.resolve(null);
414
+ }
415
+ let cwd;
416
+ try {
417
+ cwd = process.cwd?.() ?? ".";
418
+ } catch {
419
+ return Promise.resolve(null);
420
+ }
421
+ return resolveGitState(cwd).catch(() => null);
422
+ }
423
+ var GIT_TIMEOUT_MS, GIT_MAX_BUFFER, DISABLE_ENV, SHA_PATTERN;
424
+ var init_gitState = __esm({
425
+ "src/gitState.ts"() {
426
+ "use strict";
427
+ init_gitCommand();
428
+ GIT_TIMEOUT_MS = 3e4;
429
+ GIT_MAX_BUFFER = 1024 * 1024;
430
+ DISABLE_ENV = "BITFAB_DISABLE_GIT_STATE";
431
+ SHA_PATTERN = /^[0-9a-f]{40}$/;
432
+ }
433
+ });
434
+
235
435
  // src/replayContext.ts
236
436
  function getReplayContext() {
237
437
  return replayContextStorage?.getStore() ?? null;
@@ -1953,6 +2153,7 @@ var init_http = __esm({
1953
2153
  init_compress();
1954
2154
  init_constants();
1955
2155
  init_errors();
2156
+ init_gitState();
1956
2157
  init_replayContext();
1957
2158
  init_serializePayload();
1958
2159
  init_simulationPlan();
@@ -2564,6 +2765,10 @@ var init_http = __esm({
2564
2765
  if (onlyWithAssertions) {
2565
2766
  payload.onlyWithAssertions = true;
2566
2767
  }
2768
+ const git = await resolvedGitState();
2769
+ if (git && !isEmptyGitState(git)) {
2770
+ payload.git = git;
2771
+ }
2567
2772
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
2568
2773
  return this.request("/api/sdk/replay/start", payload, {
2569
2774
  timeout
@@ -2911,112 +3116,6 @@ var init_randomUuid = __esm({
2911
3116
  }
2912
3117
  });
2913
3118
 
2914
- // src/gitCommand.ts
2915
- function isUnrefable(value) {
2916
- return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2917
- }
2918
- function unrefStream(stream) {
2919
- if (isUnrefable(stream)) {
2920
- stream.unref();
2921
- }
2922
- }
2923
- function terminate(child) {
2924
- if (child.pid && process.platform !== "win32") {
2925
- try {
2926
- process.kill(-child.pid, "SIGTERM");
2927
- return;
2928
- } catch {
2929
- child.kill("SIGTERM");
2930
- return;
2931
- }
2932
- }
2933
- child.kill("SIGTERM");
2934
- }
2935
- async function gitRunner(options) {
2936
- let spawn;
2937
- try {
2938
- ;
2939
- ({ spawn } = await import("child_process"));
2940
- } catch {
2941
- return null;
2942
- }
2943
- return (dir, args) => new Promise((resolve) => {
2944
- let child;
2945
- try {
2946
- child = spawn("git", args, {
2947
- cwd: dir,
2948
- detached: process.platform !== "win32",
2949
- stdio: ["ignore", "pipe", "pipe"]
2950
- });
2951
- } catch {
2952
- resolve(null);
2953
- return;
2954
- }
2955
- const chunks = [];
2956
- let size = 0;
2957
- let overflow = false;
2958
- let exitCode = null;
2959
- let done = false;
2960
- const timers = [];
2961
- const schedule = (callback, ms) => {
2962
- const timer = setTimeout(callback, ms);
2963
- if (!options.keepProcessAlive) {
2964
- timer.unref();
2965
- }
2966
- timers.push(timer);
2967
- };
2968
- const finish = () => {
2969
- if (done) {
2970
- return;
2971
- }
2972
- done = true;
2973
- for (const timer of timers) {
2974
- clearTimeout(timer);
2975
- }
2976
- child.stdout?.destroy();
2977
- child.stderr?.destroy();
2978
- resolve(
2979
- exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2980
- );
2981
- };
2982
- child.stdout?.on("data", (chunk) => {
2983
- size += chunk.length;
2984
- if (size > options.maxBuffer) {
2985
- overflow = true;
2986
- terminate(child);
2987
- return;
2988
- }
2989
- chunks.push(chunk);
2990
- });
2991
- child.stderr?.resume();
2992
- child.on("error", () => {
2993
- exitCode = null;
2994
- finish();
2995
- });
2996
- child.on("exit", (code) => {
2997
- exitCode = code;
2998
- schedule(finish, EXIT_GRACE_MS);
2999
- });
3000
- child.on("close", (code) => {
3001
- exitCode = code ?? exitCode;
3002
- finish();
3003
- });
3004
- schedule(() => terminate(child), options.timeoutMs);
3005
- if (!options.keepProcessAlive) {
3006
- child.unref();
3007
- unrefStream(child.stdout);
3008
- unrefStream(child.stderr);
3009
- }
3010
- });
3011
- }
3012
- var EXIT_GRACE_MS;
3013
- var init_gitCommand = __esm({
3014
- "src/gitCommand.ts"() {
3015
- "use strict";
3016
- EXIT_GRACE_MS = 500;
3017
- }
3018
- });
3019
-
3020
3119
  // src/mockOverride.ts
3021
3120
  function resolveMockValue(value, ctx) {
3022
3121
  return typeof value === "function" ? value(ctx) : value;
@@ -5325,9 +5424,9 @@ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunc
5325
5424
  init_gitCommand();
5326
5425
  init_readEnv();
5327
5426
  var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
5328
- var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
5329
- var GIT_TIMEOUT_MS = 2e3;
5330
- var GIT_MAX_BUFFER = 1024 * 1024;
5427
+ var DISABLE_ENV2 = "BITFAB_DISABLE_COMMIT_REF";
5428
+ var GIT_TIMEOUT_MS2 = 2e3;
5429
+ var GIT_MAX_BUFFER2 = 1024 * 1024;
5331
5430
  var VERCEL_PROVIDER_HOSTS = {
5332
5431
  github: "github.com",
5333
5432
  gitlab: "gitlab.com",
@@ -5383,9 +5482,9 @@ var PLATFORM_ENVS = [
5383
5482
  ];
5384
5483
  var COMMIT_REF_ENV_NAMES = [
5385
5484
  EXPLICIT_SHA_ENV,
5386
- DISABLE_ENV,
5485
+ DISABLE_ENV2,
5387
5486
  ...PLATFORM_ENVS.flatMap(
5388
- ([sha, branch]) => branch === null ? [sha] : [sha, branch]
5487
+ ([sha2, branch]) => branch === null ? [sha2] : [sha2, branch]
5389
5488
  ),
5390
5489
  "GITHUB_SERVER_URL",
5391
5490
  "GITHUB_REPOSITORY",
@@ -5430,7 +5529,7 @@ function normalizeRemote(raw) {
5430
5529
  }
5431
5530
  function resolveCommitRefFromEnv(env) {
5432
5531
  const explicit = read(env, EXPLICIT_SHA_ENV);
5433
- const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
5532
+ const platform = PLATFORM_ENVS.find(([sha2]) => read(env, sha2) !== null);
5434
5533
  if (!platform) {
5435
5534
  if (explicit === null) {
5436
5535
  return null;
@@ -5454,16 +5553,16 @@ function resolveCommitRefFromEnv(env) {
5454
5553
  }
5455
5554
  async function resolveCommitRefFromGit(cwd) {
5456
5555
  const git = await gitRunner({
5457
- timeoutMs: GIT_TIMEOUT_MS,
5458
- maxBuffer: GIT_MAX_BUFFER,
5556
+ timeoutMs: GIT_TIMEOUT_MS2,
5557
+ maxBuffer: GIT_MAX_BUFFER2,
5459
5558
  keepProcessAlive: false
5460
5559
  });
5461
5560
  if (!git) {
5462
5561
  return null;
5463
5562
  }
5464
5563
  const run = async (args) => (await git(cwd, args))?.trim() ?? null;
5465
- const sha = await run(["rev-parse", "HEAD"]);
5466
- if (!sha) {
5564
+ const sha2 = await run(["rev-parse", "HEAD"]);
5565
+ if (!sha2) {
5467
5566
  return null;
5468
5567
  }
5469
5568
  const [branch, status, remote, roots] = await Promise.all([
@@ -5473,7 +5572,7 @@ async function resolveCommitRefFromGit(cwd) {
5473
5572
  run(["rev-list", "--max-parents=0", "HEAD"])
5474
5573
  ]);
5475
5574
  return {
5476
- sha,
5575
+ sha: sha2,
5477
5576
  branch: branch || null,
5478
5577
  dirty: status === null ? null : status.length > 0,
5479
5578
  remote: normalizeRemote(remote),
@@ -5497,7 +5596,7 @@ function startCommitRefResolution() {
5497
5596
  if (resolved || gitStarted) {
5498
5597
  return;
5499
5598
  }
5500
- if (read(readEnv, DISABLE_ENV) !== null) {
5599
+ if (read(readEnv, DISABLE_ENV2) !== null) {
5501
5600
  resolved = true;
5502
5601
  return;
5503
5602
  }
@@ -7078,14 +7177,14 @@ function modelLabel(model) {
7078
7177
  }
7079
7178
  function summarizeGenerate(result, model) {
7080
7179
  const content = Array.isArray(result.content) ? result.content : [];
7081
- const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7180
+ const text2 = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7082
7181
  const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
7083
7182
  toolCallId: p.toolCallId,
7084
7183
  toolName: p.toolName,
7085
7184
  input: p.input ?? p.args
7086
7185
  }));
7087
7186
  const summary = {
7088
- text,
7187
+ text: text2,
7089
7188
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7090
7189
  usage: result.usage,
7091
7190
  finishReason: result.finishReason
@@ -7097,7 +7196,7 @@ function summarizeGenerate(result, model) {
7097
7196
  }
7098
7197
  function accumulateStream(source, onComplete, model) {
7099
7198
  const reader = source.getReader();
7100
- let text = "";
7199
+ let text2 = "";
7101
7200
  const toolCalls = [];
7102
7201
  let usage;
7103
7202
  let finishReason;
@@ -7119,7 +7218,7 @@ function accumulateStream(source, onComplete, model) {
7119
7218
  }
7120
7219
  }
7121
7220
  onComplete({
7122
- text,
7221
+ text: text2,
7123
7222
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7124
7223
  usage,
7125
7224
  finishReason,
@@ -7164,7 +7263,7 @@ function accumulateStream(source, onComplete, model) {
7164
7263
  }
7165
7264
  try {
7166
7265
  if (part?.type === "text-delta") {
7167
- text += part.delta ?? part.textDelta ?? "";
7266
+ text2 += part.delta ?? part.textDelta ?? "";
7168
7267
  } else if (part?.type === "tool-call") {
7169
7268
  toolCalls.push({
7170
7269
  toolCallId: part.toolCallId,
@@ -9653,7 +9752,7 @@ async function settle(value) {
9653
9752
  }
9654
9753
  async function aiSdk(result) {
9655
9754
  const r = result ?? {};
9656
- const [text, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9755
+ const [text2, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9657
9756
  settle(r.text),
9658
9757
  settle(r.usage),
9659
9758
  settle(r.totalUsage),
@@ -9662,7 +9761,7 @@ async function aiSdk(result) {
9662
9761
  settle(r.toolResults)
9663
9762
  ]);
9664
9763
  return {
9665
- text,
9764
+ text: text2,
9666
9765
  usage: totalUsage ?? usage,
9667
9766
  finishReason,
9668
9767
  toolCalls,