bitfab 0.17.0 → 0.18.0

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
@@ -442,7 +442,7 @@ __export(index_exports, {
442
442
  module.exports = __toCommonJS(index_exports);
443
443
 
444
444
  // src/version.generated.ts
445
- var __version__ = "0.17.0";
445
+ var __version__ = "0.18.0";
446
446
 
447
447
  // src/constants.ts
448
448
  var DEFAULT_SERVICE_URL = "https://bitfab.ai";
@@ -3074,6 +3074,9 @@ var Bitfab = class {
3074
3074
  };
3075
3075
  return runWithSpanStack(newStack, executeWithContext);
3076
3076
  };
3077
+ Object.defineProperty(wrappedFn, "_bitfabTraceFunctionKey", {
3078
+ value: traceFunctionKey
3079
+ });
3077
3080
  return wrappedFn;
3078
3081
  }
3079
3082
  /**
@@ -3245,23 +3248,40 @@ var Bitfab = class {
3245
3248
  * Fetches the last N traces for the given trace function key, re-runs each
3246
3249
  * through the provided function, and returns comparison data.
3247
3250
  *
3248
- * The function must have been wrapped with `withSpan` replay injects
3249
- * `testRunId` via async context so new spans are linked to the test run.
3251
+ * Accepts either a `withSpan`-wrapped function (under the same key) or any
3252
+ * plain callable: plain callables are wrapped internally so each replayed
3253
+ * invocation records a trace tied to the test run. The plain-callable form
3254
+ * is how handler-instrumented workflows (LangGraph/LangChain, Claude Agent
3255
+ * SDK) replay — those record traces under a key with no `withSpan`-wrapped
3256
+ * root in the app.
3250
3257
  *
3251
3258
  * @param traceFunctionKey - The trace function key to replay
3252
- * @param fn - The function to replay (must be the return value of `withSpan`)
3259
+ * @param fn - The function to run recorded inputs through
3253
3260
  * @param options - Optional replay options. When `traceIds` is passed,
3254
3261
  * `limit` is ignored (with a warning): an explicit ID list already
3255
3262
  * determines how many traces replay.
3256
3263
  * @returns ReplayResult with items, testRunId, and testRunUrl
3257
3264
  */
3258
3265
  async replay(traceFunctionKey, fn, options) {
3266
+ const wrappedKey = fn._bitfabTraceFunctionKey;
3267
+ let replayFn = fn;
3268
+ if (wrappedKey === void 0) {
3269
+ replayFn = this.withSpan(
3270
+ traceFunctionKey,
3271
+ { name: fn.name || "Replay", type: "agent" },
3272
+ fn
3273
+ );
3274
+ } else if (wrappedKey !== traceFunctionKey) {
3275
+ throw new BitfabError(
3276
+ `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.`
3277
+ );
3278
+ }
3259
3279
  const { replay: doReplay } = await Promise.resolve().then(() => (init_replay(), replay_exports));
3260
3280
  return doReplay(
3261
3281
  this.httpClient,
3262
3282
  this.serviceUrl,
3263
3283
  traceFunctionKey,
3264
- fn,
3284
+ replayFn,
3265
3285
  options
3266
3286
  );
3267
3287
  }