@bitfab/sdk 0.23.0 → 0.23.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/{chunk-QOPP5TSO.js → chunk-PP5K6RIU.js} +176 -4
- package/dist/chunk-PP5K6RIU.js.map +1 -0
- package/dist/index.cjs +176 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -6
- package/dist/index.d.ts +154 -6
- package/dist/index.js +3 -1
- package/dist/node.cjs +176 -3
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +3 -1
- package/dist/node.js.map +1 -1
- package/package.json +7 -2
- package/dist/chunk-QOPP5TSO.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -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
|
*
|
|
@@ -330,6 +446,14 @@ declare class BitfabLangGraphCallbackHandler {
|
|
|
330
446
|
* replayable with no hand-written `withSpan`. The processor's spans nest
|
|
331
447
|
* underneath it automatically (it remaps onto the active span context).
|
|
332
448
|
*
|
|
449
|
+
* When `wrapRun` runs inside an enclosing Bitfab span (the replay auto-wrap, or
|
|
450
|
+
* a caller's own `withSpan`), that span is already the replayable root: the
|
|
451
|
+
* handler skips opening a second one and lets the processor nest the run's spans
|
|
452
|
+
* under the existing root. This mirrors the Claude Agent SDK and LangGraph
|
|
453
|
+
* handlers, which no-op their root span under an enclosing span, and keeps a
|
|
454
|
+
* replayed run's span tree identical to the original (no doubled root agent
|
|
455
|
+
* span).
|
|
456
|
+
*
|
|
333
457
|
* Use both together: register the processor once at startup, then call
|
|
334
458
|
* `handler.wrapRun(agent, input)` instead of `run(agent, input)`.
|
|
335
459
|
*/
|
|
@@ -339,6 +463,7 @@ type RootSpanOptions = {
|
|
|
339
463
|
finalize: (result: unknown) => unknown | Promise<unknown>;
|
|
340
464
|
};
|
|
341
465
|
type WithSpanFn = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: RootSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
|
|
466
|
+
type GetActiveSpanContextFn = () => unknown | null;
|
|
342
467
|
type RunInput<TContext, TAgent extends Agent<any, any>> = string | AgentInputItem[] | RunState<TContext, TAgent>;
|
|
343
468
|
/**
|
|
344
469
|
* OpenAI Agents SDK handler that records a replayable root span around a run.
|
|
@@ -361,9 +486,11 @@ type RunInput<TContext, TAgent extends Agent<any, any>> = string | AgentInputIte
|
|
|
361
486
|
declare class BitfabOpenAIAgentHandler {
|
|
362
487
|
private readonly traceFunctionKey;
|
|
363
488
|
private readonly withSpanFn;
|
|
489
|
+
private readonly getActiveSpanContext?;
|
|
364
490
|
constructor(config: {
|
|
365
491
|
traceFunctionKey: string;
|
|
366
492
|
withSpan: WithSpanFn;
|
|
493
|
+
getActiveSpanContext?: GetActiveSpanContextFn;
|
|
367
494
|
});
|
|
368
495
|
/**
|
|
369
496
|
* Drop-in replacement for the OpenAI Agents SDK's `run()` that records a
|
|
@@ -694,10 +821,6 @@ declare class BitfabOpenAITracingProcessor implements TracingProcessor {
|
|
|
694
821
|
private sendSpan;
|
|
695
822
|
}
|
|
696
823
|
|
|
697
|
-
/**
|
|
698
|
-
* Bitfab client for provider-based API calls.
|
|
699
|
-
*/
|
|
700
|
-
|
|
701
824
|
/**
|
|
702
825
|
* Options for wrapBAML.
|
|
703
826
|
*/
|
|
@@ -1014,6 +1137,31 @@ declare class Bitfab {
|
|
|
1014
1137
|
* @returns A BitfabClaudeAgentHandler configured for this client
|
|
1015
1138
|
*/
|
|
1016
1139
|
getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
|
|
1140
|
+
/**
|
|
1141
|
+
* Get a Vercel AI SDK language-model middleware for tracing.
|
|
1142
|
+
*
|
|
1143
|
+
* Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
|
|
1144
|
+
* `generateText` / `streamText` / `generateObject` / `streamObject`. Every
|
|
1145
|
+
* call through that model is captured as a keyed `llm` span carrying the call
|
|
1146
|
+
* parameters (the prompt) as input and a serializable summary
|
|
1147
|
+
* (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
|
|
1148
|
+
* captured without disturbing the caller's live stream.
|
|
1149
|
+
*
|
|
1150
|
+
* ```typescript
|
|
1151
|
+
* import { wrapLanguageModel, streamText } from "ai";
|
|
1152
|
+
* import { openai } from "@ai-sdk/openai";
|
|
1153
|
+
*
|
|
1154
|
+
* const model = wrapLanguageModel({
|
|
1155
|
+
* model: openai("gpt-4o"),
|
|
1156
|
+
* middleware: client.getVercelAiMiddleware("chat-turn"),
|
|
1157
|
+
* });
|
|
1158
|
+
* const result = streamText({ model, messages });
|
|
1159
|
+
* ```
|
|
1160
|
+
*
|
|
1161
|
+
* @param traceFunctionKey - Groups traces under this key in Bitfab
|
|
1162
|
+
* @returns A Vercel AI SDK middleware configured for this client
|
|
1163
|
+
*/
|
|
1164
|
+
getVercelAiMiddleware(traceFunctionKey: string): BitfabLanguageModelMiddleware;
|
|
1017
1165
|
/**
|
|
1018
1166
|
* Wrap a BAML client method to automatically capture prompt and LLM metadata.
|
|
1019
1167
|
*
|
|
@@ -1210,7 +1358,7 @@ declare class BitfabFunction {
|
|
|
1210
1358
|
/**
|
|
1211
1359
|
* SDK version from package.json (injected at build time)
|
|
1212
1360
|
*/
|
|
1213
|
-
declare const __version__ = "0.23.
|
|
1361
|
+
declare const __version__ = "0.23.2";
|
|
1214
1362
|
|
|
1215
1363
|
/**
|
|
1216
1364
|
* Constants for the Bitfab SDK.
|
|
@@ -1278,4 +1426,4 @@ declare const finalizers: {
|
|
|
1278
1426
|
readableStream: typeof readableStream;
|
|
1279
1427
|
};
|
|
1280
1428
|
|
|
1281
|
-
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 };
|
|
1429
|
+
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
|
@@ -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
|
*
|
|
@@ -330,6 +446,14 @@ declare class BitfabLangGraphCallbackHandler {
|
|
|
330
446
|
* replayable with no hand-written `withSpan`. The processor's spans nest
|
|
331
447
|
* underneath it automatically (it remaps onto the active span context).
|
|
332
448
|
*
|
|
449
|
+
* When `wrapRun` runs inside an enclosing Bitfab span (the replay auto-wrap, or
|
|
450
|
+
* a caller's own `withSpan`), that span is already the replayable root: the
|
|
451
|
+
* handler skips opening a second one and lets the processor nest the run's spans
|
|
452
|
+
* under the existing root. This mirrors the Claude Agent SDK and LangGraph
|
|
453
|
+
* handlers, which no-op their root span under an enclosing span, and keeps a
|
|
454
|
+
* replayed run's span tree identical to the original (no doubled root agent
|
|
455
|
+
* span).
|
|
456
|
+
*
|
|
333
457
|
* Use both together: register the processor once at startup, then call
|
|
334
458
|
* `handler.wrapRun(agent, input)` instead of `run(agent, input)`.
|
|
335
459
|
*/
|
|
@@ -339,6 +463,7 @@ type RootSpanOptions = {
|
|
|
339
463
|
finalize: (result: unknown) => unknown | Promise<unknown>;
|
|
340
464
|
};
|
|
341
465
|
type WithSpanFn = <TArgs extends unknown[], TReturn>(traceFunctionKey: string, options: RootSpanOptions, fn: (...args: TArgs) => TReturn) => (...args: TArgs) => TReturn;
|
|
466
|
+
type GetActiveSpanContextFn = () => unknown | null;
|
|
342
467
|
type RunInput<TContext, TAgent extends Agent<any, any>> = string | AgentInputItem[] | RunState<TContext, TAgent>;
|
|
343
468
|
/**
|
|
344
469
|
* OpenAI Agents SDK handler that records a replayable root span around a run.
|
|
@@ -361,9 +486,11 @@ type RunInput<TContext, TAgent extends Agent<any, any>> = string | AgentInputIte
|
|
|
361
486
|
declare class BitfabOpenAIAgentHandler {
|
|
362
487
|
private readonly traceFunctionKey;
|
|
363
488
|
private readonly withSpanFn;
|
|
489
|
+
private readonly getActiveSpanContext?;
|
|
364
490
|
constructor(config: {
|
|
365
491
|
traceFunctionKey: string;
|
|
366
492
|
withSpan: WithSpanFn;
|
|
493
|
+
getActiveSpanContext?: GetActiveSpanContextFn;
|
|
367
494
|
});
|
|
368
495
|
/**
|
|
369
496
|
* Drop-in replacement for the OpenAI Agents SDK's `run()` that records a
|
|
@@ -694,10 +821,6 @@ declare class BitfabOpenAITracingProcessor implements TracingProcessor {
|
|
|
694
821
|
private sendSpan;
|
|
695
822
|
}
|
|
696
823
|
|
|
697
|
-
/**
|
|
698
|
-
* Bitfab client for provider-based API calls.
|
|
699
|
-
*/
|
|
700
|
-
|
|
701
824
|
/**
|
|
702
825
|
* Options for wrapBAML.
|
|
703
826
|
*/
|
|
@@ -1014,6 +1137,31 @@ declare class Bitfab {
|
|
|
1014
1137
|
* @returns A BitfabClaudeAgentHandler configured for this client
|
|
1015
1138
|
*/
|
|
1016
1139
|
getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
|
|
1140
|
+
/**
|
|
1141
|
+
* Get a Vercel AI SDK language-model middleware for tracing.
|
|
1142
|
+
*
|
|
1143
|
+
* Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
|
|
1144
|
+
* `generateText` / `streamText` / `generateObject` / `streamObject`. Every
|
|
1145
|
+
* call through that model is captured as a keyed `llm` span carrying the call
|
|
1146
|
+
* parameters (the prompt) as input and a serializable summary
|
|
1147
|
+
* (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
|
|
1148
|
+
* captured without disturbing the caller's live stream.
|
|
1149
|
+
*
|
|
1150
|
+
* ```typescript
|
|
1151
|
+
* import { wrapLanguageModel, streamText } from "ai";
|
|
1152
|
+
* import { openai } from "@ai-sdk/openai";
|
|
1153
|
+
*
|
|
1154
|
+
* const model = wrapLanguageModel({
|
|
1155
|
+
* model: openai("gpt-4o"),
|
|
1156
|
+
* middleware: client.getVercelAiMiddleware("chat-turn"),
|
|
1157
|
+
* });
|
|
1158
|
+
* const result = streamText({ model, messages });
|
|
1159
|
+
* ```
|
|
1160
|
+
*
|
|
1161
|
+
* @param traceFunctionKey - Groups traces under this key in Bitfab
|
|
1162
|
+
* @returns A Vercel AI SDK middleware configured for this client
|
|
1163
|
+
*/
|
|
1164
|
+
getVercelAiMiddleware(traceFunctionKey: string): BitfabLanguageModelMiddleware;
|
|
1017
1165
|
/**
|
|
1018
1166
|
* Wrap a BAML client method to automatically capture prompt and LLM metadata.
|
|
1019
1167
|
*
|
|
@@ -1210,7 +1358,7 @@ declare class BitfabFunction {
|
|
|
1210
1358
|
/**
|
|
1211
1359
|
* SDK version from package.json (injected at build time)
|
|
1212
1360
|
*/
|
|
1213
|
-
declare const __version__ = "0.23.
|
|
1361
|
+
declare const __version__ = "0.23.2";
|
|
1214
1362
|
|
|
1215
1363
|
/**
|
|
1216
1364
|
* Constants for the Bitfab SDK.
|
|
@@ -1278,4 +1426,4 @@ declare const finalizers: {
|
|
|
1278
1426
|
readableStream: typeof readableStream;
|
|
1279
1427
|
};
|
|
1280
1428
|
|
|
1281
|
-
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 };
|
|
1429
|
+
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
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
BitfabLangGraphCallbackHandler,
|
|
6
6
|
BitfabOpenAIAgentHandler,
|
|
7
7
|
BitfabOpenAITracingProcessor,
|
|
8
|
+
BitfabVercelAiHandler,
|
|
8
9
|
DEFAULT_SERVICE_URL,
|
|
9
10
|
ReplayEnvironment,
|
|
10
11
|
SUPPORTED_PROVIDERS,
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
flushTraces,
|
|
14
15
|
getCurrentSpan,
|
|
15
16
|
getCurrentTrace
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PP5K6RIU.js";
|
|
17
18
|
import {
|
|
18
19
|
BitfabError
|
|
19
20
|
} from "./chunk-EQI6ZJC3.js";
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
BitfabLangGraphCallbackHandler,
|
|
27
28
|
BitfabOpenAIAgentHandler,
|
|
28
29
|
BitfabOpenAITracingProcessor,
|
|
30
|
+
BitfabVercelAiHandler,
|
|
29
31
|
DEFAULT_SERVICE_URL,
|
|
30
32
|
ReplayEnvironment,
|
|
31
33
|
SUPPORTED_PROVIDERS,
|
package/dist/node.cjs
CHANGED
|
@@ -486,6 +486,7 @@ __export(node_exports, {
|
|
|
486
486
|
BitfabLangGraphCallbackHandler: () => BitfabLangGraphCallbackHandler,
|
|
487
487
|
BitfabOpenAIAgentHandler: () => BitfabOpenAIAgentHandler,
|
|
488
488
|
BitfabOpenAITracingProcessor: () => BitfabOpenAITracingProcessor,
|
|
489
|
+
BitfabVercelAiHandler: () => BitfabVercelAiHandler,
|
|
489
490
|
DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
|
|
490
491
|
ReplayEnvironment: () => ReplayEnvironment,
|
|
491
492
|
SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
|
|
@@ -505,7 +506,7 @@ registerAsyncLocalStorageClass(
|
|
|
505
506
|
);
|
|
506
507
|
|
|
507
508
|
// src/version.generated.ts
|
|
508
|
-
var __version__ = "0.23.
|
|
509
|
+
var __version__ = "0.23.2";
|
|
509
510
|
|
|
510
511
|
// src/constants.ts
|
|
511
512
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -2293,9 +2294,17 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
2293
2294
|
constructor(config) {
|
|
2294
2295
|
this.traceFunctionKey = config.traceFunctionKey;
|
|
2295
2296
|
this.withSpanFn = config.withSpan;
|
|
2297
|
+
this.getActiveSpanContext = config.getActiveSpanContext;
|
|
2296
2298
|
}
|
|
2297
2299
|
async wrapRun(agent, input, options) {
|
|
2298
2300
|
const { run } = await import("@openai/agents");
|
|
2301
|
+
if (this.getActiveSpanContext?.() != null) {
|
|
2302
|
+
return run(
|
|
2303
|
+
agent,
|
|
2304
|
+
input,
|
|
2305
|
+
options
|
|
2306
|
+
);
|
|
2307
|
+
}
|
|
2299
2308
|
const isStreaming = options?.stream === true;
|
|
2300
2309
|
const finalize = async (result) => {
|
|
2301
2310
|
const res = result;
|
|
@@ -2611,6 +2620,135 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2611
2620
|
}
|
|
2612
2621
|
};
|
|
2613
2622
|
|
|
2623
|
+
// src/vercelAiSdk.ts
|
|
2624
|
+
function modelLabel(model) {
|
|
2625
|
+
if (!model || typeof model !== "object") {
|
|
2626
|
+
return void 0;
|
|
2627
|
+
}
|
|
2628
|
+
const m = model;
|
|
2629
|
+
const provider = typeof m.provider === "string" ? m.provider : void 0;
|
|
2630
|
+
const modelId = typeof m.modelId === "string" ? m.modelId : void 0;
|
|
2631
|
+
if (provider == null && modelId == null) {
|
|
2632
|
+
return void 0;
|
|
2633
|
+
}
|
|
2634
|
+
return { provider, modelId };
|
|
2635
|
+
}
|
|
2636
|
+
function summarizeGenerate(result, model) {
|
|
2637
|
+
const content = Array.isArray(result.content) ? result.content : [];
|
|
2638
|
+
const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
|
|
2639
|
+
const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
|
|
2640
|
+
toolCallId: p.toolCallId,
|
|
2641
|
+
toolName: p.toolName,
|
|
2642
|
+
input: p.input ?? p.args
|
|
2643
|
+
}));
|
|
2644
|
+
const summary = {
|
|
2645
|
+
text,
|
|
2646
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
2647
|
+
usage: result.usage,
|
|
2648
|
+
finishReason: result.finishReason
|
|
2649
|
+
};
|
|
2650
|
+
if (model) {
|
|
2651
|
+
summary.model = model;
|
|
2652
|
+
}
|
|
2653
|
+
return summary;
|
|
2654
|
+
}
|
|
2655
|
+
function accumulateStream(onComplete, model) {
|
|
2656
|
+
let text = "";
|
|
2657
|
+
const toolCalls = [];
|
|
2658
|
+
let usage;
|
|
2659
|
+
let finishReason;
|
|
2660
|
+
let completed = false;
|
|
2661
|
+
const complete = () => {
|
|
2662
|
+
if (completed) {
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
completed = true;
|
|
2666
|
+
const summary = {
|
|
2667
|
+
text,
|
|
2668
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
2669
|
+
usage,
|
|
2670
|
+
finishReason
|
|
2671
|
+
};
|
|
2672
|
+
if (model) {
|
|
2673
|
+
summary.model = model;
|
|
2674
|
+
}
|
|
2675
|
+
onComplete(summary);
|
|
2676
|
+
};
|
|
2677
|
+
return new TransformStream({
|
|
2678
|
+
transform(part, controller) {
|
|
2679
|
+
try {
|
|
2680
|
+
if (part?.type === "text-delta") {
|
|
2681
|
+
text += part.delta ?? part.textDelta ?? "";
|
|
2682
|
+
} else if (part?.type === "tool-call") {
|
|
2683
|
+
toolCalls.push({
|
|
2684
|
+
toolCallId: part.toolCallId,
|
|
2685
|
+
toolName: part.toolName,
|
|
2686
|
+
input: part.input ?? part.args
|
|
2687
|
+
});
|
|
2688
|
+
} else if (part?.type === "finish") {
|
|
2689
|
+
usage = part.usage;
|
|
2690
|
+
finishReason = part.finishReason;
|
|
2691
|
+
complete();
|
|
2692
|
+
}
|
|
2693
|
+
} catch {
|
|
2694
|
+
}
|
|
2695
|
+
controller.enqueue(part);
|
|
2696
|
+
},
|
|
2697
|
+
flush() {
|
|
2698
|
+
complete();
|
|
2699
|
+
}
|
|
2700
|
+
});
|
|
2701
|
+
}
|
|
2702
|
+
var BitfabVercelAiHandler = class {
|
|
2703
|
+
constructor(config) {
|
|
2704
|
+
this.traceFunctionKey = config.traceFunctionKey;
|
|
2705
|
+
this.withSpanFn = config.withSpan;
|
|
2706
|
+
}
|
|
2707
|
+
/** The `wrapLanguageModel` middleware object for this trace function key. */
|
|
2708
|
+
get middleware() {
|
|
2709
|
+
const key = this.traceFunctionKey;
|
|
2710
|
+
const withSpan = this.withSpanFn;
|
|
2711
|
+
return {
|
|
2712
|
+
specificationVersion: "v3",
|
|
2713
|
+
wrapGenerate: async ({ doGenerate, params, model }) => {
|
|
2714
|
+
const label = modelLabel(model);
|
|
2715
|
+
const traced = withSpan(
|
|
2716
|
+
key,
|
|
2717
|
+
{
|
|
2718
|
+
type: "llm",
|
|
2719
|
+
finalize: (result) => summarizeGenerate(result ?? {}, label)
|
|
2720
|
+
},
|
|
2721
|
+
() => doGenerate()
|
|
2722
|
+
);
|
|
2723
|
+
return traced(params);
|
|
2724
|
+
},
|
|
2725
|
+
wrapStream: async ({ doStream, params, model }) => {
|
|
2726
|
+
const label = modelLabel(model);
|
|
2727
|
+
let resolveSummary = () => {
|
|
2728
|
+
};
|
|
2729
|
+
const summary = new Promise((resolve) => {
|
|
2730
|
+
resolveSummary = resolve;
|
|
2731
|
+
});
|
|
2732
|
+
const traced = withSpan(
|
|
2733
|
+
key,
|
|
2734
|
+
// The wrapped fn returns immediately with the live stream, so the span
|
|
2735
|
+
// output cannot be read from the return value. `finalize` instead
|
|
2736
|
+
// awaits the summary the accumulator resolves once the stream drains.
|
|
2737
|
+
{ type: "llm", finalize: () => summary },
|
|
2738
|
+
async () => {
|
|
2739
|
+
const result = await doStream();
|
|
2740
|
+
const stream = result.stream.pipeThrough(
|
|
2741
|
+
accumulateStream(resolveSummary, label)
|
|
2742
|
+
);
|
|
2743
|
+
return { ...result, stream };
|
|
2744
|
+
}
|
|
2745
|
+
);
|
|
2746
|
+
return traced(params);
|
|
2747
|
+
}
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
};
|
|
2751
|
+
|
|
2614
2752
|
// src/client.ts
|
|
2615
2753
|
var activeTraceStates = /* @__PURE__ */ new Map();
|
|
2616
2754
|
var pendingSpanPromises = /* @__PURE__ */ new Map();
|
|
@@ -3039,7 +3177,11 @@ var Bitfab = class {
|
|
|
3039
3177
|
getOpenAiAgentHandler(traceFunctionKey) {
|
|
3040
3178
|
return new BitfabOpenAIAgentHandler({
|
|
3041
3179
|
traceFunctionKey,
|
|
3042
|
-
withSpan: this.withSpan.bind(this)
|
|
3180
|
+
withSpan: this.withSpan.bind(this),
|
|
3181
|
+
getActiveSpanContext: () => {
|
|
3182
|
+
const stack = getSpanStack();
|
|
3183
|
+
return stack[stack.length - 1] ?? null;
|
|
3184
|
+
}
|
|
3043
3185
|
});
|
|
3044
3186
|
}
|
|
3045
3187
|
/**
|
|
@@ -3122,6 +3264,36 @@ var Bitfab = class {
|
|
|
3122
3264
|
}
|
|
3123
3265
|
});
|
|
3124
3266
|
}
|
|
3267
|
+
/**
|
|
3268
|
+
* Get a Vercel AI SDK language-model middleware for tracing.
|
|
3269
|
+
*
|
|
3270
|
+
* Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
|
|
3271
|
+
* `generateText` / `streamText` / `generateObject` / `streamObject`. Every
|
|
3272
|
+
* call through that model is captured as a keyed `llm` span carrying the call
|
|
3273
|
+
* parameters (the prompt) as input and a serializable summary
|
|
3274
|
+
* (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
|
|
3275
|
+
* captured without disturbing the caller's live stream.
|
|
3276
|
+
*
|
|
3277
|
+
* ```typescript
|
|
3278
|
+
* import { wrapLanguageModel, streamText } from "ai";
|
|
3279
|
+
* import { openai } from "@ai-sdk/openai";
|
|
3280
|
+
*
|
|
3281
|
+
* const model = wrapLanguageModel({
|
|
3282
|
+
* model: openai("gpt-4o"),
|
|
3283
|
+
* middleware: client.getVercelAiMiddleware("chat-turn"),
|
|
3284
|
+
* });
|
|
3285
|
+
* const result = streamText({ model, messages });
|
|
3286
|
+
* ```
|
|
3287
|
+
*
|
|
3288
|
+
* @param traceFunctionKey - Groups traces under this key in Bitfab
|
|
3289
|
+
* @returns A Vercel AI SDK middleware configured for this client
|
|
3290
|
+
*/
|
|
3291
|
+
getVercelAiMiddleware(traceFunctionKey) {
|
|
3292
|
+
return new BitfabVercelAiHandler({
|
|
3293
|
+
traceFunctionKey,
|
|
3294
|
+
withSpan: this.withSpan.bind(this)
|
|
3295
|
+
}).middleware;
|
|
3296
|
+
}
|
|
3125
3297
|
/**
|
|
3126
3298
|
* Wrap a BAML client method to automatically capture prompt and LLM metadata.
|
|
3127
3299
|
*
|
|
@@ -3664,7 +3836,7 @@ var Bitfab = class {
|
|
|
3664
3836
|
if (wrappedKey === void 0) {
|
|
3665
3837
|
replayFn = this.withSpan(
|
|
3666
3838
|
traceFunctionKey,
|
|
3667
|
-
{ name:
|
|
3839
|
+
{ name: traceFunctionKey, type: "agent" },
|
|
3668
3840
|
fn
|
|
3669
3841
|
);
|
|
3670
3842
|
} else if (wrappedKey !== traceFunctionKey) {
|
|
@@ -3798,6 +3970,7 @@ assertAsyncStorageRegistered();
|
|
|
3798
3970
|
BitfabLangGraphCallbackHandler,
|
|
3799
3971
|
BitfabOpenAIAgentHandler,
|
|
3800
3972
|
BitfabOpenAITracingProcessor,
|
|
3973
|
+
BitfabVercelAiHandler,
|
|
3801
3974
|
DEFAULT_SERVICE_URL,
|
|
3802
3975
|
ReplayEnvironment,
|
|
3803
3976
|
SUPPORTED_PROVIDERS,
|