@bitfab/sdk 0.54.0 → 0.54.1

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.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.54.0";
45
+ __version__ = "0.54.1";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -186,6 +186,206 @@ var init_errors = __esm({
186
186
  }
187
187
  });
188
188
 
189
+ // src/gitCommand.ts
190
+ function isUnrefable(value) {
191
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
192
+ }
193
+ function unrefStream(stream) {
194
+ if (isUnrefable(stream)) {
195
+ stream.unref();
196
+ }
197
+ }
198
+ function terminate(child) {
199
+ if (child.pid && process.platform !== "win32") {
200
+ try {
201
+ process.kill(-child.pid, "SIGTERM");
202
+ return;
203
+ } catch {
204
+ child.kill("SIGTERM");
205
+ return;
206
+ }
207
+ }
208
+ child.kill("SIGTERM");
209
+ }
210
+ async function gitRunner(options) {
211
+ let spawn;
212
+ try {
213
+ ;
214
+ ({ spawn } = await import("child_process"));
215
+ } catch {
216
+ return null;
217
+ }
218
+ return (dir, args, env) => new Promise((resolve) => {
219
+ let child;
220
+ try {
221
+ child = spawn("git", args, {
222
+ cwd: dir,
223
+ detached: process.platform !== "win32",
224
+ stdio: ["ignore", "pipe", "pipe"],
225
+ ...env ? { env: { ...process.env, ...env } } : {}
226
+ });
227
+ } catch {
228
+ resolve(null);
229
+ return;
230
+ }
231
+ const chunks = [];
232
+ let size = 0;
233
+ let overflow = false;
234
+ let exitCode = null;
235
+ let done = false;
236
+ const timers = [];
237
+ const schedule = (callback, ms) => {
238
+ const timer = setTimeout(callback, ms);
239
+ if (!options.keepProcessAlive) {
240
+ timer.unref();
241
+ }
242
+ timers.push(timer);
243
+ };
244
+ const finish = () => {
245
+ if (done) {
246
+ return;
247
+ }
248
+ done = true;
249
+ for (const timer of timers) {
250
+ clearTimeout(timer);
251
+ }
252
+ child.stdout?.destroy();
253
+ child.stderr?.destroy();
254
+ resolve(
255
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
256
+ );
257
+ };
258
+ child.stdout?.on("data", (chunk) => {
259
+ size += chunk.length;
260
+ if (size > options.maxBuffer) {
261
+ overflow = true;
262
+ terminate(child);
263
+ return;
264
+ }
265
+ chunks.push(chunk);
266
+ });
267
+ child.stderr?.resume();
268
+ child.on("error", () => {
269
+ exitCode = null;
270
+ finish();
271
+ });
272
+ child.on("exit", (code) => {
273
+ exitCode = code;
274
+ schedule(finish, EXIT_GRACE_MS);
275
+ });
276
+ child.on("close", (code) => {
277
+ exitCode = code ?? exitCode;
278
+ finish();
279
+ });
280
+ schedule(() => terminate(child), options.timeoutMs);
281
+ if (!options.keepProcessAlive) {
282
+ child.unref();
283
+ unrefStream(child.stdout);
284
+ unrefStream(child.stderr);
285
+ }
286
+ });
287
+ }
288
+ var EXIT_GRACE_MS;
289
+ var init_gitCommand = __esm({
290
+ "src/gitCommand.ts"() {
291
+ "use strict";
292
+ EXIT_GRACE_MS = 500;
293
+ }
294
+ });
295
+
296
+ // src/gitState.ts
297
+ function sha(value) {
298
+ const trimmed = value?.trim();
299
+ return trimmed && SHA_PATTERN.test(trimmed) ? trimmed : null;
300
+ }
301
+ function text(value) {
302
+ const trimmed = value?.trim();
303
+ return trimmed ? trimmed : null;
304
+ }
305
+ function isEmptyGitState(state) {
306
+ return Object.values(state).every((value) => value === null);
307
+ }
308
+ async function resolveGitState(cwd) {
309
+ const git = await gitRunner({
310
+ timeoutMs: GIT_TIMEOUT_MS,
311
+ maxBuffer: GIT_MAX_BUFFER,
312
+ keepProcessAlive: true
313
+ });
314
+ if (!git) {
315
+ return null;
316
+ }
317
+ const run = async (args, env) => (await git(cwd, args, env))?.trim() ?? null;
318
+ const [refs, email, branch] = await Promise.all([
319
+ run(["rev-parse", "--show-toplevel", "HEAD", "HEAD^{tree}"]),
320
+ run(["config", "user.email"]),
321
+ run(["symbolic-ref", "--short", "-q", "HEAD"])
322
+ ]);
323
+ const [root, commitSha, baseSha] = (refs ?? "").split("\n");
324
+ if (!root) {
325
+ return null;
326
+ }
327
+ const state = {
328
+ githubEmail: text(email),
329
+ branch: text(branch),
330
+ commitSha: sha(commitSha),
331
+ baseSha: sha(baseSha),
332
+ experimentSha: await resolveWorkingTreeSha(run, root.trim())
333
+ };
334
+ return isEmptyGitState(state) ? null : state;
335
+ }
336
+ async function resolveWorkingTreeSha(run, root) {
337
+ let indexPath;
338
+ let cleanup;
339
+ try {
340
+ const { mkdtemp, rm } = await import("fs/promises");
341
+ const { join } = await import("path");
342
+ const { tmpdir } = await import("os");
343
+ const dir = await mkdtemp(join(tmpdir(), "bitfab-git-"));
344
+ indexPath = join(dir, "index");
345
+ cleanup = () => rm(dir, { recursive: true, force: true });
346
+ } catch {
347
+ return null;
348
+ }
349
+ try {
350
+ const env = { GIT_INDEX_FILE: indexPath };
351
+ if (await run(["read-tree", "HEAD"], env) === null) {
352
+ return null;
353
+ }
354
+ if (await run(["add", "-A", "--", root], env) === null) {
355
+ return null;
356
+ }
357
+ return sha(await run(["write-tree"], env));
358
+ } catch {
359
+ return null;
360
+ } finally {
361
+ await cleanup().catch(() => {
362
+ });
363
+ }
364
+ }
365
+ function resolvedGitState() {
366
+ if (typeof process === "undefined" || process.env?.[DISABLE_ENV]) {
367
+ return Promise.resolve(null);
368
+ }
369
+ let cwd;
370
+ try {
371
+ cwd = process.cwd?.() ?? ".";
372
+ } catch {
373
+ return Promise.resolve(null);
374
+ }
375
+ return resolveGitState(cwd).catch(() => null);
376
+ }
377
+ var GIT_TIMEOUT_MS, GIT_MAX_BUFFER, DISABLE_ENV, SHA_PATTERN;
378
+ var init_gitState = __esm({
379
+ "src/gitState.ts"() {
380
+ "use strict";
381
+ init_gitCommand();
382
+ GIT_TIMEOUT_MS = 3e4;
383
+ GIT_MAX_BUFFER = 1024 * 1024;
384
+ DISABLE_ENV = "BITFAB_DISABLE_GIT_STATE";
385
+ SHA_PATTERN = /^[0-9a-f]{40}$/;
386
+ }
387
+ });
388
+
189
389
  // src/asyncStorage.ts
190
390
  function registerAsyncLocalStorageClass(cls) {
191
391
  if (!AsyncLocalStorageClass) {
@@ -1946,6 +2146,7 @@ var init_http = __esm({
1946
2146
  init_compress();
1947
2147
  init_constants();
1948
2148
  init_errors();
2149
+ init_gitState();
1949
2150
  init_replayContext();
1950
2151
  init_serializePayload();
1951
2152
  init_simulationPlan();
@@ -2557,6 +2758,10 @@ var init_http = __esm({
2557
2758
  if (onlyWithAssertions) {
2558
2759
  payload.onlyWithAssertions = true;
2559
2760
  }
2761
+ const git = await resolvedGitState();
2762
+ if (git && !isEmptyGitState(git)) {
2763
+ payload.git = git;
2764
+ }
2560
2765
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
2561
2766
  return this.request("/api/sdk/replay/start", payload, {
2562
2767
  timeout
@@ -2904,112 +3109,6 @@ var init_randomUuid = __esm({
2904
3109
  }
2905
3110
  });
2906
3111
 
2907
- // src/gitCommand.ts
2908
- function isUnrefable(value) {
2909
- return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2910
- }
2911
- function unrefStream(stream) {
2912
- if (isUnrefable(stream)) {
2913
- stream.unref();
2914
- }
2915
- }
2916
- function terminate(child) {
2917
- if (child.pid && process.platform !== "win32") {
2918
- try {
2919
- process.kill(-child.pid, "SIGTERM");
2920
- return;
2921
- } catch {
2922
- child.kill("SIGTERM");
2923
- return;
2924
- }
2925
- }
2926
- child.kill("SIGTERM");
2927
- }
2928
- async function gitRunner(options) {
2929
- let spawn;
2930
- try {
2931
- ;
2932
- ({ spawn } = await import("child_process"));
2933
- } catch {
2934
- return null;
2935
- }
2936
- return (dir, args) => new Promise((resolve) => {
2937
- let child;
2938
- try {
2939
- child = spawn("git", args, {
2940
- cwd: dir,
2941
- detached: process.platform !== "win32",
2942
- stdio: ["ignore", "pipe", "pipe"]
2943
- });
2944
- } catch {
2945
- resolve(null);
2946
- return;
2947
- }
2948
- const chunks = [];
2949
- let size = 0;
2950
- let overflow = false;
2951
- let exitCode = null;
2952
- let done = false;
2953
- const timers = [];
2954
- const schedule = (callback, ms) => {
2955
- const timer = setTimeout(callback, ms);
2956
- if (!options.keepProcessAlive) {
2957
- timer.unref();
2958
- }
2959
- timers.push(timer);
2960
- };
2961
- const finish = () => {
2962
- if (done) {
2963
- return;
2964
- }
2965
- done = true;
2966
- for (const timer of timers) {
2967
- clearTimeout(timer);
2968
- }
2969
- child.stdout?.destroy();
2970
- child.stderr?.destroy();
2971
- resolve(
2972
- exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2973
- );
2974
- };
2975
- child.stdout?.on("data", (chunk) => {
2976
- size += chunk.length;
2977
- if (size > options.maxBuffer) {
2978
- overflow = true;
2979
- terminate(child);
2980
- return;
2981
- }
2982
- chunks.push(chunk);
2983
- });
2984
- child.stderr?.resume();
2985
- child.on("error", () => {
2986
- exitCode = null;
2987
- finish();
2988
- });
2989
- child.on("exit", (code) => {
2990
- exitCode = code;
2991
- schedule(finish, EXIT_GRACE_MS);
2992
- });
2993
- child.on("close", (code) => {
2994
- exitCode = code ?? exitCode;
2995
- finish();
2996
- });
2997
- schedule(() => terminate(child), options.timeoutMs);
2998
- if (!options.keepProcessAlive) {
2999
- child.unref();
3000
- unrefStream(child.stdout);
3001
- unrefStream(child.stderr);
3002
- }
3003
- });
3004
- }
3005
- var EXIT_GRACE_MS;
3006
- var init_gitCommand = __esm({
3007
- "src/gitCommand.ts"() {
3008
- "use strict";
3009
- EXIT_GRACE_MS = 500;
3010
- }
3011
- });
3012
-
3013
3112
  // src/mockOverride.ts
3014
3113
  function resolveMockValue(value, ctx) {
3015
3114
  return typeof value === "function" ? value(ctx) : value;
@@ -5311,9 +5410,9 @@ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunc
5311
5410
  init_gitCommand();
5312
5411
  init_readEnv();
5313
5412
  var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
5314
- var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
5315
- var GIT_TIMEOUT_MS = 2e3;
5316
- var GIT_MAX_BUFFER = 1024 * 1024;
5413
+ var DISABLE_ENV2 = "BITFAB_DISABLE_COMMIT_REF";
5414
+ var GIT_TIMEOUT_MS2 = 2e3;
5415
+ var GIT_MAX_BUFFER2 = 1024 * 1024;
5317
5416
  var VERCEL_PROVIDER_HOSTS = {
5318
5417
  github: "github.com",
5319
5418
  gitlab: "gitlab.com",
@@ -5369,9 +5468,9 @@ var PLATFORM_ENVS = [
5369
5468
  ];
5370
5469
  var COMMIT_REF_ENV_NAMES = [
5371
5470
  EXPLICIT_SHA_ENV,
5372
- DISABLE_ENV,
5471
+ DISABLE_ENV2,
5373
5472
  ...PLATFORM_ENVS.flatMap(
5374
- ([sha, branch]) => branch === null ? [sha] : [sha, branch]
5473
+ ([sha2, branch]) => branch === null ? [sha2] : [sha2, branch]
5375
5474
  ),
5376
5475
  "GITHUB_SERVER_URL",
5377
5476
  "GITHUB_REPOSITORY",
@@ -5416,7 +5515,7 @@ function normalizeRemote(raw) {
5416
5515
  }
5417
5516
  function resolveCommitRefFromEnv(env) {
5418
5517
  const explicit = read(env, EXPLICIT_SHA_ENV);
5419
- const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
5518
+ const platform = PLATFORM_ENVS.find(([sha2]) => read(env, sha2) !== null);
5420
5519
  if (!platform) {
5421
5520
  if (explicit === null) {
5422
5521
  return null;
@@ -5440,16 +5539,16 @@ function resolveCommitRefFromEnv(env) {
5440
5539
  }
5441
5540
  async function resolveCommitRefFromGit(cwd) {
5442
5541
  const git = await gitRunner({
5443
- timeoutMs: GIT_TIMEOUT_MS,
5444
- maxBuffer: GIT_MAX_BUFFER,
5542
+ timeoutMs: GIT_TIMEOUT_MS2,
5543
+ maxBuffer: GIT_MAX_BUFFER2,
5445
5544
  keepProcessAlive: false
5446
5545
  });
5447
5546
  if (!git) {
5448
5547
  return null;
5449
5548
  }
5450
5549
  const run = async (args) => (await git(cwd, args))?.trim() ?? null;
5451
- const sha = await run(["rev-parse", "HEAD"]);
5452
- if (!sha) {
5550
+ const sha2 = await run(["rev-parse", "HEAD"]);
5551
+ if (!sha2) {
5453
5552
  return null;
5454
5553
  }
5455
5554
  const [branch, status, remote, roots] = await Promise.all([
@@ -5459,7 +5558,7 @@ async function resolveCommitRefFromGit(cwd) {
5459
5558
  run(["rev-list", "--max-parents=0", "HEAD"])
5460
5559
  ]);
5461
5560
  return {
5462
- sha,
5561
+ sha: sha2,
5463
5562
  branch: branch || null,
5464
5563
  dirty: status === null ? null : status.length > 0,
5465
5564
  remote: normalizeRemote(remote),
@@ -5483,7 +5582,7 @@ function startCommitRefResolution() {
5483
5582
  if (resolved || gitStarted) {
5484
5583
  return;
5485
5584
  }
5486
- if (read(readEnv, DISABLE_ENV) !== null) {
5585
+ if (read(readEnv, DISABLE_ENV2) !== null) {
5487
5586
  resolved = true;
5488
5587
  return;
5489
5588
  }
@@ -7064,14 +7163,14 @@ function modelLabel(model) {
7064
7163
  }
7065
7164
  function summarizeGenerate(result, model) {
7066
7165
  const content = Array.isArray(result.content) ? result.content : [];
7067
- const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7166
+ const text2 = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7068
7167
  const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
7069
7168
  toolCallId: p.toolCallId,
7070
7169
  toolName: p.toolName,
7071
7170
  input: p.input ?? p.args
7072
7171
  }));
7073
7172
  const summary = {
7074
- text,
7173
+ text: text2,
7075
7174
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7076
7175
  usage: result.usage,
7077
7176
  finishReason: result.finishReason
@@ -7083,7 +7182,7 @@ function summarizeGenerate(result, model) {
7083
7182
  }
7084
7183
  function accumulateStream(source, onComplete, model) {
7085
7184
  const reader = source.getReader();
7086
- let text = "";
7185
+ let text2 = "";
7087
7186
  const toolCalls = [];
7088
7187
  let usage;
7089
7188
  let finishReason;
@@ -7105,7 +7204,7 @@ function accumulateStream(source, onComplete, model) {
7105
7204
  }
7106
7205
  }
7107
7206
  onComplete({
7108
- text,
7207
+ text: text2,
7109
7208
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7110
7209
  usage,
7111
7210
  finishReason,
@@ -7150,7 +7249,7 @@ function accumulateStream(source, onComplete, model) {
7150
7249
  }
7151
7250
  try {
7152
7251
  if (part?.type === "text-delta") {
7153
- text += part.delta ?? part.textDelta ?? "";
7252
+ text2 += part.delta ?? part.textDelta ?? "";
7154
7253
  } else if (part?.type === "tool-call") {
7155
7254
  toolCalls.push({
7156
7255
  toolCallId: part.toolCallId,
@@ -9639,7 +9738,7 @@ async function settle(value) {
9639
9738
  }
9640
9739
  async function aiSdk(result) {
9641
9740
  const r = result ?? {};
9642
- const [text, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9741
+ const [text2, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9643
9742
  settle(r.text),
9644
9743
  settle(r.usage),
9645
9744
  settle(r.totalUsage),
@@ -9648,7 +9747,7 @@ async function aiSdk(result) {
9648
9747
  settle(r.toolResults)
9649
9748
  ]);
9650
9749
  return {
9651
- text,
9750
+ text: text2,
9652
9751
  usage: totalUsage ?? usage,
9653
9752
  finishReason,
9654
9753
  toolCalls,