bitfab 0.23.1 → 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.
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-EQI6ZJC3.js";
11
11
 
12
12
  // src/version.generated.ts
13
- var __version__ = "0.23.1";
13
+ var __version__ = "0.23.2";
14
14
 
15
15
  // src/constants.ts
16
16
  var DEFAULT_SERVICE_URL = "https://bitfab.ai";
@@ -2110,6 +2110,135 @@ var BitfabOpenAITracingProcessor = class {
2110
2110
  }
2111
2111
  };
2112
2112
 
2113
+ // src/vercelAiSdk.ts
2114
+ function modelLabel(model) {
2115
+ if (!model || typeof model !== "object") {
2116
+ return void 0;
2117
+ }
2118
+ const m = model;
2119
+ const provider = typeof m.provider === "string" ? m.provider : void 0;
2120
+ const modelId = typeof m.modelId === "string" ? m.modelId : void 0;
2121
+ if (provider == null && modelId == null) {
2122
+ return void 0;
2123
+ }
2124
+ return { provider, modelId };
2125
+ }
2126
+ function summarizeGenerate(result, model) {
2127
+ const content = Array.isArray(result.content) ? result.content : [];
2128
+ const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
2129
+ const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
2130
+ toolCallId: p.toolCallId,
2131
+ toolName: p.toolName,
2132
+ input: p.input ?? p.args
2133
+ }));
2134
+ const summary = {
2135
+ text,
2136
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
2137
+ usage: result.usage,
2138
+ finishReason: result.finishReason
2139
+ };
2140
+ if (model) {
2141
+ summary.model = model;
2142
+ }
2143
+ return summary;
2144
+ }
2145
+ function accumulateStream(onComplete, model) {
2146
+ let text = "";
2147
+ const toolCalls = [];
2148
+ let usage;
2149
+ let finishReason;
2150
+ let completed = false;
2151
+ const complete = () => {
2152
+ if (completed) {
2153
+ return;
2154
+ }
2155
+ completed = true;
2156
+ const summary = {
2157
+ text,
2158
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
2159
+ usage,
2160
+ finishReason
2161
+ };
2162
+ if (model) {
2163
+ summary.model = model;
2164
+ }
2165
+ onComplete(summary);
2166
+ };
2167
+ return new TransformStream({
2168
+ transform(part, controller) {
2169
+ try {
2170
+ if (part?.type === "text-delta") {
2171
+ text += part.delta ?? part.textDelta ?? "";
2172
+ } else if (part?.type === "tool-call") {
2173
+ toolCalls.push({
2174
+ toolCallId: part.toolCallId,
2175
+ toolName: part.toolName,
2176
+ input: part.input ?? part.args
2177
+ });
2178
+ } else if (part?.type === "finish") {
2179
+ usage = part.usage;
2180
+ finishReason = part.finishReason;
2181
+ complete();
2182
+ }
2183
+ } catch {
2184
+ }
2185
+ controller.enqueue(part);
2186
+ },
2187
+ flush() {
2188
+ complete();
2189
+ }
2190
+ });
2191
+ }
2192
+ var BitfabVercelAiHandler = class {
2193
+ constructor(config) {
2194
+ this.traceFunctionKey = config.traceFunctionKey;
2195
+ this.withSpanFn = config.withSpan;
2196
+ }
2197
+ /** The `wrapLanguageModel` middleware object for this trace function key. */
2198
+ get middleware() {
2199
+ const key = this.traceFunctionKey;
2200
+ const withSpan = this.withSpanFn;
2201
+ return {
2202
+ specificationVersion: "v3",
2203
+ wrapGenerate: async ({ doGenerate, params, model }) => {
2204
+ const label = modelLabel(model);
2205
+ const traced = withSpan(
2206
+ key,
2207
+ {
2208
+ type: "llm",
2209
+ finalize: (result) => summarizeGenerate(result ?? {}, label)
2210
+ },
2211
+ () => doGenerate()
2212
+ );
2213
+ return traced(params);
2214
+ },
2215
+ wrapStream: async ({ doStream, params, model }) => {
2216
+ const label = modelLabel(model);
2217
+ let resolveSummary = () => {
2218
+ };
2219
+ const summary = new Promise((resolve) => {
2220
+ resolveSummary = resolve;
2221
+ });
2222
+ const traced = withSpan(
2223
+ key,
2224
+ // The wrapped fn returns immediately with the live stream, so the span
2225
+ // output cannot be read from the return value. `finalize` instead
2226
+ // awaits the summary the accumulator resolves once the stream drains.
2227
+ { type: "llm", finalize: () => summary },
2228
+ async () => {
2229
+ const result = await doStream();
2230
+ const stream = result.stream.pipeThrough(
2231
+ accumulateStream(resolveSummary, label)
2232
+ );
2233
+ return { ...result, stream };
2234
+ }
2235
+ );
2236
+ return traced(params);
2237
+ }
2238
+ };
2239
+ }
2240
+ };
2241
+
2113
2242
  // src/client.ts
2114
2243
  var activeTraceStates = /* @__PURE__ */ new Map();
2115
2244
  var pendingSpanPromises = /* @__PURE__ */ new Map();
@@ -2625,6 +2754,36 @@ var Bitfab = class {
2625
2754
  }
2626
2755
  });
2627
2756
  }
2757
+ /**
2758
+ * Get a Vercel AI SDK language-model middleware for tracing.
2759
+ *
2760
+ * Pass it to the AI SDK's `wrapLanguageModel` and use the wrapped model with
2761
+ * `generateText` / `streamText` / `generateObject` / `streamObject`. Every
2762
+ * call through that model is captured as a keyed `llm` span carrying the call
2763
+ * parameters (the prompt) as input and a serializable summary
2764
+ * (`{ text, toolCalls, usage, finishReason }`) as output. Streaming is
2765
+ * captured without disturbing the caller's live stream.
2766
+ *
2767
+ * ```typescript
2768
+ * import { wrapLanguageModel, streamText } from "ai";
2769
+ * import { openai } from "@ai-sdk/openai";
2770
+ *
2771
+ * const model = wrapLanguageModel({
2772
+ * model: openai("gpt-4o"),
2773
+ * middleware: client.getVercelAiMiddleware("chat-turn"),
2774
+ * });
2775
+ * const result = streamText({ model, messages });
2776
+ * ```
2777
+ *
2778
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
2779
+ * @returns A Vercel AI SDK middleware configured for this client
2780
+ */
2781
+ getVercelAiMiddleware(traceFunctionKey) {
2782
+ return new BitfabVercelAiHandler({
2783
+ traceFunctionKey,
2784
+ withSpan: this.withSpan.bind(this)
2785
+ }).middleware;
2786
+ }
2628
2787
  /**
2629
2788
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
2630
2789
  *
@@ -3298,10 +3457,11 @@ export {
3298
3457
  BitfabOpenAIAgentHandler,
3299
3458
  ReplayEnvironment,
3300
3459
  BitfabOpenAITracingProcessor,
3460
+ BitfabVercelAiHandler,
3301
3461
  getCurrentSpan,
3302
3462
  getCurrentTrace,
3303
3463
  Bitfab,
3304
3464
  BitfabFunction,
3305
3465
  finalizers
3306
3466
  };
3307
- //# sourceMappingURL=chunk-2EDITKO2.js.map
3467
+ //# sourceMappingURL=chunk-PP5K6RIU.js.map