bitfab 0.23.1 → 0.23.3

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
@@ -1,4 +1,4 @@
1
- import { Agent, AgentInputItem, RunState, NonStreamRunOptions, RunResult, StreamRunOptions, StreamedRunResult, Trace, Span } from '@openai/agents';
1
+ import { Agent, AgentInputItem, RunState, NonStreamRunOptions, RunResult, StreamRunOptions, StreamedRunResult } from '@openai/agents';
2
2
 
3
3
  /**
4
4
  * BAML execution utilities for the Bitfab TypeScript SDK.
@@ -171,6 +171,122 @@ declare class BitfabClaudeAgentHandler {
171
171
  private resetState;
172
172
  }
173
173
 
174
+ /**
175
+ * Vercel AI SDK integration for Bitfab tracing.
176
+ *
177
+ * The Vercel AI SDK (`ai`) routes every `generateText` / `streamText` /
178
+ * `generateObject` / `streamObject` call through a language model. Bitfab hooks
179
+ * that model with a *language-model middleware* (`wrapLanguageModel`), so each
180
+ * model call is captured as a keyed `llm` span with no hand-written `withSpan`:
181
+ *
182
+ * ```typescript
183
+ * import { Bitfab } from "@bitfab/sdk";
184
+ * import { wrapLanguageModel, streamText } from "ai";
185
+ * import { openai } from "@ai-sdk/openai";
186
+ *
187
+ * const bitfab = new Bitfab({ apiKey: "..." });
188
+ *
189
+ * const model = wrapLanguageModel({
190
+ * model: openai("gpt-4o"),
191
+ * middleware: bitfab.getVercelAiMiddleware("chat-turn"),
192
+ * });
193
+ *
194
+ * const result = streamText({ model, messages });
195
+ * return result.toUIMessageStreamResponse(); // live stream untouched
196
+ * ```
197
+ *
198
+ * The span records the call parameters (the prompt/messages) as its input and a
199
+ * serializable summary (`{ text, toolCalls, usage, finishReason }`) as its
200
+ * output. Streaming is handled by passing the model's stream through a
201
+ * transform that accumulates the assembled text/usage as the caller consumes
202
+ * it: the live stream is handed back unchanged (first-byte latency untouched)
203
+ * and the span is finalized once the stream completes.
204
+ *
205
+ * The middleware is fully duck-typed (no static or dynamic `ai` import), so it
206
+ * adds no dependency and is browser-safe. It works with `ai` v5 and v6.
207
+ */
208
+ type LlmSpanOptions = {
209
+ type: "llm";
210
+ finalize: (result: unknown) => unknown | Promise<unknown>;
211
+ };
212
+ type WithSpanFn$1 = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: LlmSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
213
+ /**
214
+ * Duck-typed subset of the Vercel AI SDK language-model call parameters. The
215
+ * only field we read for the span input is `prompt` (the messages), but the
216
+ * whole object is recorded so the call is reconstructable on replay.
217
+ */
218
+ interface VercelCallParams {
219
+ prompt?: unknown;
220
+ [key: string]: unknown;
221
+ }
222
+ /** A content part of a non-streaming `doGenerate` result. */
223
+ interface VercelContentPart {
224
+ type: string;
225
+ text?: string;
226
+ toolCallId?: string;
227
+ toolName?: string;
228
+ input?: unknown;
229
+ args?: unknown;
230
+ }
231
+ /** Duck-typed subset of a non-streaming `doGenerate` result. */
232
+ interface VercelGenerateResult {
233
+ content?: VercelContentPart[];
234
+ text?: string;
235
+ usage?: unknown;
236
+ finishReason?: unknown;
237
+ [key: string]: unknown;
238
+ }
239
+ /** Duck-typed subset of a single streaming part from `doStream`. */
240
+ interface VercelStreamPart {
241
+ type: string;
242
+ delta?: string;
243
+ textDelta?: string;
244
+ toolCallId?: string;
245
+ toolName?: string;
246
+ input?: unknown;
247
+ args?: unknown;
248
+ usage?: unknown;
249
+ finishReason?: unknown;
250
+ }
251
+ /** Duck-typed subset of a streaming `doStream` result. */
252
+ interface VercelStreamResult {
253
+ stream: ReadableStream<VercelStreamPart>;
254
+ [key: string]: unknown;
255
+ }
256
+ interface MiddlewareCall<TResult> {
257
+ doGenerate: () => PromiseLike<VercelGenerateResult>;
258
+ doStream: () => PromiseLike<VercelStreamResult>;
259
+ params: VercelCallParams;
260
+ model: unknown;
261
+ __result?: TResult;
262
+ }
263
+ /**
264
+ * The structural shape of a Vercel AI SDK language-model middleware. Matches
265
+ * `LanguageModelV3Middleware` from `@ai-sdk/provider` without importing it, so
266
+ * the SDK stays dependency-free. `wrapLanguageModel` only reads the method
267
+ * fields (it ignores `specificationVersion`), so this object drops straight in.
268
+ */
269
+ interface BitfabLanguageModelMiddleware {
270
+ specificationVersion: "v3";
271
+ wrapGenerate: (options: MiddlewareCall<VercelGenerateResult>) => Promise<any>;
272
+ wrapStream: (options: MiddlewareCall<VercelStreamResult>) => Promise<any>;
273
+ }
274
+ /**
275
+ * Vercel AI SDK middleware that records each language-model call as a keyed
276
+ * `llm` span. Obtain it from {@link BitfabClient.getVercelAiMiddleware} rather
277
+ * than constructing it directly.
278
+ */
279
+ declare class BitfabVercelAiHandler {
280
+ private readonly traceFunctionKey;
281
+ private readonly withSpanFn;
282
+ constructor(config: {
283
+ traceFunctionKey: string;
284
+ withSpan: WithSpanFn$1;
285
+ });
286
+ /** The `wrapLanguageModel` middleware object for this trace function key. */
287
+ get middleware(): BitfabLanguageModelMiddleware;
288
+ }
289
+
174
290
  /**
175
291
  * Per-trace database snapshot ref capture.
176
292
  *
@@ -592,7 +708,19 @@ interface ReplayResult<T> {
592
708
  * This module provides utilities for sending external traces (e.g., from OpenAI API calls)
593
709
  * to Bitfab for monitoring and analysis.
594
710
  */
595
-
711
+ interface Trace {
712
+ traceId: string;
713
+ toJSON(): unknown;
714
+ }
715
+ interface Span<_T = any> {
716
+ traceId?: string;
717
+ toJSON(): unknown;
718
+ spanData?: {
719
+ type?: string;
720
+ _input?: unknown;
721
+ _response?: unknown;
722
+ } | null;
723
+ }
596
724
  interface TraceResponse {
597
725
  traceId: string;
598
726
  status: "success";
@@ -705,10 +833,6 @@ declare class BitfabOpenAITracingProcessor implements TracingProcessor {
705
833
  private sendSpan;
706
834
  }
707
835
 
708
- /**
709
- * Bitfab client for provider-based API calls.
710
- */
711
-
712
836
  /**
713
837
  * Options for wrapBAML.
714
838
  */
@@ -1025,6 +1149,31 @@ declare class Bitfab {
1025
1149
  * @returns A BitfabClaudeAgentHandler configured for this client
1026
1150
  */
1027
1151
  getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
1152
+ /**
1153
+ * Get a Vercel AI SDK language-model middleware for tracing.
1154
+ *
1155
+ * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
1156
+ * `generateText` / `streamText` / `generateObject` / `streamObject`. Every
1157
+ * call through that model is captured as a keyed `llm` span carrying the call
1158
+ * parameters (the prompt) as input and a serializable summary
1159
+ * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
1160
+ * captured without disturbing the caller's live stream.
1161
+ *
1162
+ * ```typescript
1163
+ * import { wrapLanguageModel, streamText } from "ai";
1164
+ * import { openai } from "@ai-sdk/openai";
1165
+ *
1166
+ * const model = wrapLanguageModel({
1167
+ * model: openai("gpt-4o"),
1168
+ * middleware: client.getVercelAiMiddleware("chat-turn"),
1169
+ * });
1170
+ * const result = streamText({ model, messages });
1171
+ * ```
1172
+ *
1173
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
1174
+ * @returns A Vercel AI SDK middleware configured for this client
1175
+ */
1176
+ getVercelAiMiddleware(traceFunctionKey: string): BitfabLanguageModelMiddleware;
1028
1177
  /**
1029
1178
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
1030
1179
  *
@@ -1221,7 +1370,7 @@ declare class BitfabFunction {
1221
1370
  /**
1222
1371
  * SDK version from package.json (injected at build time)
1223
1372
  */
1224
- declare const __version__ = "0.23.1";
1373
+ declare const __version__ = "0.23.3";
1225
1374
 
1226
1375
  /**
1227
1376
  * Constants for the Bitfab SDK.
@@ -1289,4 +1438,4 @@ declare const finalizers: {
1289
1438
  readableStream: typeof readableStream;
1290
1439
  };
1291
1440
 
1292
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
1441
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Agent, AgentInputItem, RunState, NonStreamRunOptions, RunResult, StreamRunOptions, StreamedRunResult, Trace, Span } from '@openai/agents';
1
+ import { Agent, AgentInputItem, RunState, NonStreamRunOptions, RunResult, StreamRunOptions, StreamedRunResult } from '@openai/agents';
2
2
 
3
3
  /**
4
4
  * BAML execution utilities for the Bitfab TypeScript SDK.
@@ -171,6 +171,122 @@ declare class BitfabClaudeAgentHandler {
171
171
  private resetState;
172
172
  }
173
173
 
174
+ /**
175
+ * Vercel AI SDK integration for Bitfab tracing.
176
+ *
177
+ * The Vercel AI SDK (`ai`) routes every `generateText` / `streamText` /
178
+ * `generateObject` / `streamObject` call through a language model. Bitfab hooks
179
+ * that model with a *language-model middleware* (`wrapLanguageModel`), so each
180
+ * model call is captured as a keyed `llm` span with no hand-written `withSpan`:
181
+ *
182
+ * ```typescript
183
+ * import { Bitfab } from "@bitfab/sdk";
184
+ * import { wrapLanguageModel, streamText } from "ai";
185
+ * import { openai } from "@ai-sdk/openai";
186
+ *
187
+ * const bitfab = new Bitfab({ apiKey: "..." });
188
+ *
189
+ * const model = wrapLanguageModel({
190
+ * model: openai("gpt-4o"),
191
+ * middleware: bitfab.getVercelAiMiddleware("chat-turn"),
192
+ * });
193
+ *
194
+ * const result = streamText({ model, messages });
195
+ * return result.toUIMessageStreamResponse(); // live stream untouched
196
+ * ```
197
+ *
198
+ * The span records the call parameters (the prompt/messages) as its input and a
199
+ * serializable summary (`{ text, toolCalls, usage, finishReason }`) as its
200
+ * output. Streaming is handled by passing the model's stream through a
201
+ * transform that accumulates the assembled text/usage as the caller consumes
202
+ * it: the live stream is handed back unchanged (first-byte latency untouched)
203
+ * and the span is finalized once the stream completes.
204
+ *
205
+ * The middleware is fully duck-typed (no static or dynamic `ai` import), so it
206
+ * adds no dependency and is browser-safe. It works with `ai` v5 and v6.
207
+ */
208
+ type LlmSpanOptions = {
209
+ type: "llm";
210
+ finalize: (result: unknown) => unknown | Promise<unknown>;
211
+ };
212
+ type WithSpanFn$1 = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: LlmSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
213
+ /**
214
+ * Duck-typed subset of the Vercel AI SDK language-model call parameters. The
215
+ * only field we read for the span input is `prompt` (the messages), but the
216
+ * whole object is recorded so the call is reconstructable on replay.
217
+ */
218
+ interface VercelCallParams {
219
+ prompt?: unknown;
220
+ [key: string]: unknown;
221
+ }
222
+ /** A content part of a non-streaming `doGenerate` result. */
223
+ interface VercelContentPart {
224
+ type: string;
225
+ text?: string;
226
+ toolCallId?: string;
227
+ toolName?: string;
228
+ input?: unknown;
229
+ args?: unknown;
230
+ }
231
+ /** Duck-typed subset of a non-streaming `doGenerate` result. */
232
+ interface VercelGenerateResult {
233
+ content?: VercelContentPart[];
234
+ text?: string;
235
+ usage?: unknown;
236
+ finishReason?: unknown;
237
+ [key: string]: unknown;
238
+ }
239
+ /** Duck-typed subset of a single streaming part from `doStream`. */
240
+ interface VercelStreamPart {
241
+ type: string;
242
+ delta?: string;
243
+ textDelta?: string;
244
+ toolCallId?: string;
245
+ toolName?: string;
246
+ input?: unknown;
247
+ args?: unknown;
248
+ usage?: unknown;
249
+ finishReason?: unknown;
250
+ }
251
+ /** Duck-typed subset of a streaming `doStream` result. */
252
+ interface VercelStreamResult {
253
+ stream: ReadableStream<VercelStreamPart>;
254
+ [key: string]: unknown;
255
+ }
256
+ interface MiddlewareCall<TResult> {
257
+ doGenerate: () => PromiseLike<VercelGenerateResult>;
258
+ doStream: () => PromiseLike<VercelStreamResult>;
259
+ params: VercelCallParams;
260
+ model: unknown;
261
+ __result?: TResult;
262
+ }
263
+ /**
264
+ * The structural shape of a Vercel AI SDK language-model middleware. Matches
265
+ * `LanguageModelV3Middleware` from `@ai-sdk/provider` without importing it, so
266
+ * the SDK stays dependency-free. `wrapLanguageModel` only reads the method
267
+ * fields (it ignores `specificationVersion`), so this object drops straight in.
268
+ */
269
+ interface BitfabLanguageModelMiddleware {
270
+ specificationVersion: "v3";
271
+ wrapGenerate: (options: MiddlewareCall<VercelGenerateResult>) => Promise<any>;
272
+ wrapStream: (options: MiddlewareCall<VercelStreamResult>) => Promise<any>;
273
+ }
274
+ /**
275
+ * Vercel AI SDK middleware that records each language-model call as a keyed
276
+ * `llm` span. Obtain it from {@link BitfabClient.getVercelAiMiddleware} rather
277
+ * than constructing it directly.
278
+ */
279
+ declare class BitfabVercelAiHandler {
280
+ private readonly traceFunctionKey;
281
+ private readonly withSpanFn;
282
+ constructor(config: {
283
+ traceFunctionKey: string;
284
+ withSpan: WithSpanFn$1;
285
+ });
286
+ /** The `wrapLanguageModel` middleware object for this trace function key. */
287
+ get middleware(): BitfabLanguageModelMiddleware;
288
+ }
289
+
174
290
  /**
175
291
  * Per-trace database snapshot ref capture.
176
292
  *
@@ -592,7 +708,19 @@ interface ReplayResult<T> {
592
708
  * This module provides utilities for sending external traces (e.g., from OpenAI API calls)
593
709
  * to Bitfab for monitoring and analysis.
594
710
  */
595
-
711
+ interface Trace {
712
+ traceId: string;
713
+ toJSON(): unknown;
714
+ }
715
+ interface Span<_T = any> {
716
+ traceId?: string;
717
+ toJSON(): unknown;
718
+ spanData?: {
719
+ type?: string;
720
+ _input?: unknown;
721
+ _response?: unknown;
722
+ } | null;
723
+ }
596
724
  interface TraceResponse {
597
725
  traceId: string;
598
726
  status: "success";
@@ -705,10 +833,6 @@ declare class BitfabOpenAITracingProcessor implements TracingProcessor {
705
833
  private sendSpan;
706
834
  }
707
835
 
708
- /**
709
- * Bitfab client for provider-based API calls.
710
- */
711
-
712
836
  /**
713
837
  * Options for wrapBAML.
714
838
  */
@@ -1025,6 +1149,31 @@ declare class Bitfab {
1025
1149
  * @returns A BitfabClaudeAgentHandler configured for this client
1026
1150
  */
1027
1151
  getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
1152
+ /**
1153
+ * Get a Vercel AI SDK language-model middleware for tracing.
1154
+ *
1155
+ * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
1156
+ * `generateText` / `streamText` / `generateObject` / `streamObject`. Every
1157
+ * call through that model is captured as a keyed `llm` span carrying the call
1158
+ * parameters (the prompt) as input and a serializable summary
1159
+ * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
1160
+ * captured without disturbing the caller's live stream.
1161
+ *
1162
+ * ```typescript
1163
+ * import { wrapLanguageModel, streamText } from "ai";
1164
+ * import { openai } from "@ai-sdk/openai";
1165
+ *
1166
+ * const model = wrapLanguageModel({
1167
+ * model: openai("gpt-4o"),
1168
+ * middleware: client.getVercelAiMiddleware("chat-turn"),
1169
+ * });
1170
+ * const result = streamText({ model, messages });
1171
+ * ```
1172
+ *
1173
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
1174
+ * @returns A Vercel AI SDK middleware configured for this client
1175
+ */
1176
+ getVercelAiMiddleware(traceFunctionKey: string): BitfabLanguageModelMiddleware;
1028
1177
  /**
1029
1178
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
1030
1179
  *
@@ -1221,7 +1370,7 @@ declare class BitfabFunction {
1221
1370
  /**
1222
1371
  * SDK version from package.json (injected at build time)
1223
1372
  */
1224
- declare const __version__ = "0.23.1";
1373
+ declare const __version__ = "0.23.3";
1225
1374
 
1226
1375
  /**
1227
1376
  * Constants for the Bitfab SDK.
@@ -1289,4 +1438,4 @@ declare const finalizers: {
1289
1438
  readableStream: typeof readableStream;
1290
1439
  };
1291
1440
 
1292
- export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
1441
+ export { type ActiveSpanContext, type AdaptContext, type AdaptInputsFn, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler as BitfabLangChainCallbackHandler, BitfabLangGraphCallbackHandler, type BitfabLanguageModelMiddleware, BitfabOpenAIAgentHandler, BitfabOpenAITracingProcessor, BitfabVercelAiHandler, type CodeChangeFile, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type DbSnapshotConfig, type DbSnapshotProvider, type DbSnapshotRef, type DetachedTrace, type MockStrategy, type ProviderDefinition, ReplayEnvironment, type ReplayEnvironmentSnapshot, type ReplayItem, type ReplayOptions, type ReplayResult, SUPPORTED_PROVIDERS, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type VercelCallParams, type VercelGenerateResult, type VercelStreamResult, type WrapBAMLOptions, type WrappedBamlFn, __version__, finalizers, flushTraces, getCurrentSpan, getCurrentTrace };
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  BitfabLangGraphCallbackHandler,
15
15
  BitfabOpenAIAgentHandler,
16
16
  BitfabOpenAITracingProcessor,
17
+ BitfabVercelAiHandler,
17
18
  DEFAULT_SERVICE_URL,
18
19
  ReplayEnvironment,
19
20
  SUPPORTED_PROVIDERS,
@@ -22,7 +23,7 @@ import {
22
23
  flushTraces,
23
24
  getCurrentSpan,
24
25
  getCurrentTrace
25
- } from "./chunk-2EDITKO2.js";
26
+ } from "./chunk-CG6LVLBK.js";
26
27
  import {
27
28
  BitfabError
28
29
  } from "./chunk-EQI6ZJC3.js";
@@ -35,6 +36,7 @@ export {
35
36
  BitfabLangGraphCallbackHandler,
36
37
  BitfabOpenAIAgentHandler,
37
38
  BitfabOpenAITracingProcessor,
39
+ BitfabVercelAiHandler,
38
40
  DEFAULT_SERVICE_URL,
39
41
  ReplayEnvironment,
40
42
  SUPPORTED_PROVIDERS,
package/dist/node.cjs CHANGED
@@ -495,6 +495,7 @@ __export(node_exports, {
495
495
  BitfabLangGraphCallbackHandler: () => BitfabLangGraphCallbackHandler,
496
496
  BitfabOpenAIAgentHandler: () => BitfabOpenAIAgentHandler,
497
497
  BitfabOpenAITracingProcessor: () => BitfabOpenAITracingProcessor,
498
+ BitfabVercelAiHandler: () => BitfabVercelAiHandler,
498
499
  DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
499
500
  ReplayEnvironment: () => ReplayEnvironment,
500
501
  SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
@@ -514,7 +515,7 @@ registerAsyncLocalStorageClass(
514
515
  );
515
516
 
516
517
  // src/version.generated.ts
517
- var __version__ = "0.23.1";
518
+ var __version__ = "0.23.3";
518
519
 
519
520
  // src/constants.ts
520
521
  var DEFAULT_SERVICE_URL = "https://bitfab.ai";
@@ -1455,6 +1456,16 @@ var BitfabClaudeAgentHandler = class {
1455
1456
  // src/client.ts
1456
1457
  init_asyncStorage();
1457
1458
 
1459
+ // src/optionalPeer.ts
1460
+ function importOptionalPeer(specifierParts) {
1461
+ const specifier = specifierParts.join("/");
1462
+ return import(
1463
+ /* webpackIgnore: true */
1464
+ /* @vite-ignore */
1465
+ specifier
1466
+ );
1467
+ }
1468
+
1458
1469
  // src/baml.ts
1459
1470
  var cachedBaml = null;
1460
1471
  async function loadBaml() {
@@ -1462,7 +1473,7 @@ async function loadBaml() {
1462
1473
  return cachedBaml;
1463
1474
  }
1464
1475
  try {
1465
- cachedBaml = await import("@boundaryml/baml");
1476
+ cachedBaml = await importOptionalPeer(["@boundaryml", "baml"]);
1466
1477
  return cachedBaml;
1467
1478
  } catch {
1468
1479
  throw new Error(
@@ -2305,7 +2316,10 @@ var BitfabOpenAIAgentHandler = class {
2305
2316
  this.getActiveSpanContext = config.getActiveSpanContext;
2306
2317
  }
2307
2318
  async wrapRun(agent, input, options) {
2308
- const { run } = await import("@openai/agents");
2319
+ const { run } = await importOptionalPeer([
2320
+ "@openai",
2321
+ "agents"
2322
+ ]);
2309
2323
  if (this.getActiveSpanContext?.() != null) {
2310
2324
  return run(
2311
2325
  agent,
@@ -2628,6 +2642,135 @@ var BitfabOpenAITracingProcessor = class {
2628
2642
  }
2629
2643
  };
2630
2644
 
2645
+ // src/vercelAiSdk.ts
2646
+ function modelLabel(model) {
2647
+ if (!model || typeof model !== "object") {
2648
+ return void 0;
2649
+ }
2650
+ const m = model;
2651
+ const provider = typeof m.provider === "string" ? m.provider : void 0;
2652
+ const modelId = typeof m.modelId === "string" ? m.modelId : void 0;
2653
+ if (provider == null && modelId == null) {
2654
+ return void 0;
2655
+ }
2656
+ return { provider, modelId };
2657
+ }
2658
+ function summarizeGenerate(result, model) {
2659
+ const content = Array.isArray(result.content) ? result.content : [];
2660
+ const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
2661
+ const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
2662
+ toolCallId: p.toolCallId,
2663
+ toolName: p.toolName,
2664
+ input: p.input ?? p.args
2665
+ }));
2666
+ const summary = {
2667
+ text,
2668
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
2669
+ usage: result.usage,
2670
+ finishReason: result.finishReason
2671
+ };
2672
+ if (model) {
2673
+ summary.model = model;
2674
+ }
2675
+ return summary;
2676
+ }
2677
+ function accumulateStream(onComplete, model) {
2678
+ let text = "";
2679
+ const toolCalls = [];
2680
+ let usage;
2681
+ let finishReason;
2682
+ let completed = false;
2683
+ const complete = () => {
2684
+ if (completed) {
2685
+ return;
2686
+ }
2687
+ completed = true;
2688
+ const summary = {
2689
+ text,
2690
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
2691
+ usage,
2692
+ finishReason
2693
+ };
2694
+ if (model) {
2695
+ summary.model = model;
2696
+ }
2697
+ onComplete(summary);
2698
+ };
2699
+ return new TransformStream({
2700
+ transform(part, controller) {
2701
+ try {
2702
+ if (part?.type === "text-delta") {
2703
+ text += part.delta ?? part.textDelta ?? "";
2704
+ } else if (part?.type === "tool-call") {
2705
+ toolCalls.push({
2706
+ toolCallId: part.toolCallId,
2707
+ toolName: part.toolName,
2708
+ input: part.input ?? part.args
2709
+ });
2710
+ } else if (part?.type === "finish") {
2711
+ usage = part.usage;
2712
+ finishReason = part.finishReason;
2713
+ complete();
2714
+ }
2715
+ } catch {
2716
+ }
2717
+ controller.enqueue(part);
2718
+ },
2719
+ flush() {
2720
+ complete();
2721
+ }
2722
+ });
2723
+ }
2724
+ var BitfabVercelAiHandler = class {
2725
+ constructor(config) {
2726
+ this.traceFunctionKey = config.traceFunctionKey;
2727
+ this.withSpanFn = config.withSpan;
2728
+ }
2729
+ /** The `wrapLanguageModel` middleware object for this trace function key. */
2730
+ get middleware() {
2731
+ const key = this.traceFunctionKey;
2732
+ const withSpan = this.withSpanFn;
2733
+ return {
2734
+ specificationVersion: "v3",
2735
+ wrapGenerate: async ({ doGenerate, params, model }) => {
2736
+ const label = modelLabel(model);
2737
+ const traced = withSpan(
2738
+ key,
2739
+ {
2740
+ type: "llm",
2741
+ finalize: (result) => summarizeGenerate(result ?? {}, label)
2742
+ },
2743
+ () => doGenerate()
2744
+ );
2745
+ return traced(params);
2746
+ },
2747
+ wrapStream: async ({ doStream, params, model }) => {
2748
+ const label = modelLabel(model);
2749
+ let resolveSummary = () => {
2750
+ };
2751
+ const summary = new Promise((resolve) => {
2752
+ resolveSummary = resolve;
2753
+ });
2754
+ const traced = withSpan(
2755
+ key,
2756
+ // The wrapped fn returns immediately with the live stream, so the span
2757
+ // output cannot be read from the return value. `finalize` instead
2758
+ // awaits the summary the accumulator resolves once the stream drains.
2759
+ { type: "llm", finalize: () => summary },
2760
+ async () => {
2761
+ const result = await doStream();
2762
+ const stream = result.stream.pipeThrough(
2763
+ accumulateStream(resolveSummary, label)
2764
+ );
2765
+ return { ...result, stream };
2766
+ }
2767
+ );
2768
+ return traced(params);
2769
+ }
2770
+ };
2771
+ }
2772
+ };
2773
+
2631
2774
  // src/client.ts
2632
2775
  var activeTraceStates = /* @__PURE__ */ new Map();
2633
2776
  var pendingSpanPromises = /* @__PURE__ */ new Map();
@@ -2727,7 +2870,10 @@ async function loadCollectorClass() {
2727
2870
  return cachedCollectorClass;
2728
2871
  }
2729
2872
  try {
2730
- const baml = await import("@boundaryml/baml");
2873
+ const baml = await importOptionalPeer([
2874
+ "@boundaryml",
2875
+ "baml"
2876
+ ]);
2731
2877
  cachedCollectorClass = baml.Collector;
2732
2878
  return cachedCollectorClass;
2733
2879
  } catch {
@@ -3143,6 +3289,36 @@ var Bitfab = class {
3143
3289
  }
3144
3290
  });
3145
3291
  }
3292
+ /**
3293
+ * Get a Vercel AI SDK language-model middleware for tracing.
3294
+ *
3295
+ * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
3296
+ * `generateText` / `streamText` / `generateObject` / `streamObject`. Every
3297
+ * call through that model is captured as a keyed `llm` span carrying the call
3298
+ * parameters (the prompt) as input and a serializable summary
3299
+ * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
3300
+ * captured without disturbing the caller's live stream.
3301
+ *
3302
+ * ```typescript
3303
+ * import { wrapLanguageModel, streamText } from "ai";
3304
+ * import { openai } from "@ai-sdk/openai";
3305
+ *
3306
+ * const model = wrapLanguageModel({
3307
+ * model: openai("gpt-4o"),
3308
+ * middleware: client.getVercelAiMiddleware("chat-turn"),
3309
+ * });
3310
+ * const result = streamText({ model, messages });
3311
+ * ```
3312
+ *
3313
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
3314
+ * @returns A Vercel AI SDK middleware configured for this client
3315
+ */
3316
+ getVercelAiMiddleware(traceFunctionKey) {
3317
+ return new BitfabVercelAiHandler({
3318
+ traceFunctionKey,
3319
+ withSpan: this.withSpan.bind(this)
3320
+ }).middleware;
3321
+ }
3146
3322
  /**
3147
3323
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
3148
3324
  *
@@ -3819,6 +3995,7 @@ assertAsyncStorageRegistered();
3819
3995
  BitfabLangGraphCallbackHandler,
3820
3996
  BitfabOpenAIAgentHandler,
3821
3997
  BitfabOpenAITracingProcessor,
3998
+ BitfabVercelAiHandler,
3822
3999
  DEFAULT_SERVICE_URL,
3823
4000
  ReplayEnvironment,
3824
4001
  SUPPORTED_PROVIDERS,