bitfab 0.9.2 → 0.11.4

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
@@ -32,6 +32,118 @@ type AllowedEnvVars = {
32
32
  OPENAI_API_KEY?: string;
33
33
  };
34
34
 
35
+ /**
36
+ * Claude Agent SDK handler for Bitfab tracing.
37
+ *
38
+ * Hooks into the Claude Agent SDK's lifecycle to capture LLM turns,
39
+ * tool invocations, and subagent execution as Bitfab spans.
40
+ *
41
+ * Uses two integration surfaces:
42
+ * 1. SDK hooks (PreToolUse, PostToolUse, etc.) for tool/subagent lifecycle
43
+ * 2. Stream wrapping for LLM turn capture from the message stream
44
+ */
45
+ interface ActiveSpanContext$2 {
46
+ traceId: string;
47
+ spanId: string;
48
+ }
49
+ /**
50
+ * Claude Agent SDK handler that sends traces to Bitfab.
51
+ *
52
+ * Captures LLM turns, tool invocations, and subagent execution as
53
+ * Bitfab spans with proper parent-child hierarchy.
54
+ *
55
+ * ```typescript
56
+ * import { Bitfab } from "bitfab";
57
+ * import { ClaudeSDKClient } from "@anthropic-ai/claude-agent-sdk";
58
+ *
59
+ * const bitfab = new Bitfab({ apiKey: "..." });
60
+ * const handler = bitfab.getClaudeAgentHandler("my-agent");
61
+ *
62
+ * const options = handler.instrumentOptions({
63
+ * model: "claude-sonnet-4-5-...",
64
+ * });
65
+ *
66
+ * const client = new ClaudeSDKClient(options);
67
+ * await client.connect();
68
+ * await client.query("Do something");
69
+ *
70
+ * for await (const message of handler.wrapResponse(client.receiveResponse())) {
71
+ * // process messages normally
72
+ * }
73
+ * ```
74
+ */
75
+ declare class BitfabClaudeAgentHandler {
76
+ private readonly httpClient;
77
+ private readonly traceFunctionKey;
78
+ private readonly getActiveSpanContext;
79
+ private runToSpan;
80
+ private traceId;
81
+ private rootSpanId;
82
+ private activeContext;
83
+ private traceStartedAt;
84
+ private conversationHistory;
85
+ private pendingMessages;
86
+ private currentLlmSpanId;
87
+ private currentLlmMessageId;
88
+ private currentLlmContent;
89
+ private currentLlmModel;
90
+ private currentLlmUsage;
91
+ private currentLlmStartedAt;
92
+ private currentLlmHistorySnapshot;
93
+ private activeSubagentSpans;
94
+ constructor(config: {
95
+ apiKey?: string;
96
+ traceFunctionKey: string;
97
+ serviceUrl?: string;
98
+ timeout?: number;
99
+ getActiveSpanContext?: () => ActiveSpanContext$2 | null;
100
+ });
101
+ private ensureTrace;
102
+ private getParentId;
103
+ private startSpan;
104
+ private completeSpan;
105
+ private sendSpan;
106
+ private sendTraceCompletion;
107
+ private preToolUseHook;
108
+ private postToolUseHook;
109
+ private postToolUseFailureHook;
110
+ private subagentStartHook;
111
+ private subagentStopHook;
112
+ /**
113
+ * Inject Bitfab tracing hooks into Claude Agent SDK options.
114
+ *
115
+ * Modifies the options object and returns it for convenience.
116
+ * The SDK's `HookMatcher` is constructed as a plain object
117
+ * (`{ matcher: null, hooks: [callback] }`) to avoid requiring
118
+ * `@anthropic-ai/claude-agent-sdk` as a dependency.
119
+ *
120
+ * @param options - Options object with a `hooks` property
121
+ * @returns The modified options object with Bitfab hooks injected
122
+ */
123
+ instrumentOptions<T extends Record<string, unknown>>(options: T): T;
124
+ /**
125
+ * Wrap a `ClaudeSDKClient.receiveResponse()` stream to capture LLM turns.
126
+ *
127
+ * Yields every message unchanged while capturing AssistantMessage
128
+ * content as LLM turn spans.
129
+ */
130
+ wrapResponse(stream: AsyncIterable<unknown>): AsyncIterable<unknown>;
131
+ /**
132
+ * Wrap a `query()` async iterator to capture LLM turns.
133
+ *
134
+ * Same as `wrapResponse` but for the simpler `query()` API
135
+ * which does not support hooks (no tool/subagent spans).
136
+ */
137
+ wrapQuery(stream: AsyncIterable<unknown>): AsyncIterable<unknown>;
138
+ private processStream;
139
+ private processMessage;
140
+ private handleAssistantMessage;
141
+ private handleUserMessage;
142
+ private handleResultMessage;
143
+ private flushLlmTurn;
144
+ private resetState;
145
+ }
146
+
35
147
  /**
36
148
  * HTTP client utilities for Bitfab API requests.
37
149
  *
@@ -53,6 +165,120 @@ declare class BitfabError extends Error {
53
165
  * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)
54
166
  */
55
167
  declare function flushTraces(timeoutMs?: number): Promise<void>;
168
+ interface TokenUsage {
169
+ input: number | null;
170
+ output: number | null;
171
+ cached: number | null;
172
+ total: number | null;
173
+ }
174
+
175
+ /**
176
+ * LangGraph/LangChain callback handler for Bitfab tracing.
177
+ *
178
+ * Hooks into LangGraph's callback system to capture graph node execution,
179
+ * LLM calls, and tool invocations as Bitfab spans — without requiring users
180
+ * to wrap their functions with withSpan (which fails on non-serializable args).
181
+ *
182
+ * Duck-typed to match LangChain.js's BaseCallbackHandler interface.
183
+ * No @langchain/core dependency required.
184
+ */
185
+ interface ActiveSpanContext$1 {
186
+ traceId: string;
187
+ spanId: string;
188
+ }
189
+ /**
190
+ * LangChain/LangGraph callback handler that sends traces to Bitfab.
191
+ *
192
+ * Duck-typed to match LangChain.js's BaseCallbackHandler — no
193
+ * `@langchain/core` dependency required. Pass as a callback:
194
+ *
195
+ * ```typescript
196
+ * const handler = bitfab.getLangGraphCallbackHandler("my-agent");
197
+ * const result = await agent.invoke(
198
+ * { messages: [...] },
199
+ * { callbacks: [handler] },
200
+ * );
201
+ * ```
202
+ */
203
+ declare class BitfabLangGraphCallbackHandler {
204
+ name: string;
205
+ ignoreRetriever: boolean;
206
+ ignoreRetry: boolean;
207
+ ignoreCustomEvent: boolean;
208
+ private readonly httpClient;
209
+ private readonly traceFunctionKey;
210
+ private readonly getActiveSpanContext;
211
+ private runToSpan;
212
+ private invocations;
213
+ constructor(config: {
214
+ apiKey?: string;
215
+ traceFunctionKey: string;
216
+ serviceUrl?: string;
217
+ timeout?: number;
218
+ getActiveSpanContext?: () => ActiveSpanContext$1 | null;
219
+ });
220
+ private startSpan;
221
+ private completeSpan;
222
+ private sendSpan;
223
+ private sendTraceCompletion;
224
+ handleChainStart(chain: Record<string, unknown>, inputs: Record<string, unknown>, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
225
+ handleChainEnd(outputs: Record<string, unknown>, runId: string): Promise<void>;
226
+ handleChainError(error: unknown, runId: string): Promise<void>;
227
+ handleChatModelStart(llm: Record<string, unknown>, messages: unknown[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
228
+ handleLLMStart(llm: Record<string, unknown>, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
229
+ handleLLMEnd(output: Record<string, unknown>, runId: string): Promise<void>;
230
+ handleLLMError(error: unknown, runId: string): Promise<void>;
231
+ handleLLMNewToken(): Promise<void>;
232
+ handleToolStart(tool: Record<string, unknown>, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
233
+ handleToolEnd(output: unknown, runId: string): Promise<void>;
234
+ handleToolError(error: unknown, runId: string): Promise<void>;
235
+ handleRetrieverStart(retriever: Record<string, unknown>, query: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
236
+ handleRetrieverEnd(documents: unknown, runId: string): Promise<void>;
237
+ handleRetrieverError(error: unknown, runId: string): Promise<void>;
238
+ }
239
+
240
+ /**
241
+ * Replay historical traces through a function and create a test run.
242
+ *
243
+ * The replay flow has three phases:
244
+ * 1. Start — fetches historical traces from the server and creates a test run
245
+ * 2. Execute — re-runs each trace's inputs through the provided function locally
246
+ * 3. Complete — marks the test run as completed on the server
247
+ */
248
+
249
+ interface ReplayOptions {
250
+ /** Maximum number of traces to replay (1–100, default 5). */
251
+ limit?: number;
252
+ /** Optional list of specific trace IDs to replay. */
253
+ traceIds?: string[];
254
+ /** Maximum number of items to process in parallel. Set to 1 for sequential. Default 10. */
255
+ maxConcurrency?: number;
256
+ }
257
+ interface ReplayItem<T> {
258
+ /** Deserialized inputs from the original trace. */
259
+ input: unknown[];
260
+ /** The result returned by the function during replay, or undefined on error. */
261
+ result: T | undefined;
262
+ /** The original output from the historical trace. */
263
+ originalOutput: unknown;
264
+ /** Error message if the function threw, or null on success. */
265
+ error: string | null;
266
+ /** Original trace duration in milliseconds, or null if timestamps are missing. */
267
+ durationMs: number | null;
268
+ /** Token usage from the original trace, or null if not captured. */
269
+ tokens: TokenUsage | null;
270
+ /** Model name from the original trace, or null if not captured. */
271
+ model: string | null;
272
+ }
273
+
274
+ interface ReplayResult<T> {
275
+ /** Individual replay items with inputs, results, and comparison data. */
276
+ items: ReplayItem<T>[];
277
+ /** The test run ID created on the server. */
278
+ testRunId: string;
279
+ /** Full URL to view the test run in the dashboard. */
280
+ testRunUrl: string;
281
+ }
56
282
 
57
283
  /**
58
284
  * Tracing utilities for external trace submission to Bitfab.
@@ -89,7 +315,7 @@ interface TracingProcessor {
89
315
  *
90
316
  * Example usage:
91
317
  * ```typescript
92
- * import { Bitfab } from '@goharvest/bitfab';
318
+ * import { Bitfab } from 'bitfab';
93
319
  * import { addTraceProcessor } from '@openai/agents';
94
320
  *
95
321
  * const client = new Bitfab({ apiKey: 'your-api-key' });
@@ -337,6 +563,47 @@ declare class Bitfab {
337
563
  * @returns A BitfabOpenAITracingProcessor instance configured for this client
338
564
  */
339
565
  getOpenAiTracingProcessor(): BitfabOpenAITracingProcessor;
566
+ /**
567
+ * Get a LangGraph/LangChain callback handler for tracing.
568
+ *
569
+ * The handler captures graph node execution, LLM calls, and tool
570
+ * invocations as Bitfab spans with proper parent-child hierarchy.
571
+ *
572
+ * ```typescript
573
+ * const handler = client.getLangGraphCallbackHandler("my-agent");
574
+ * const result = await agent.invoke(
575
+ * { messages: [...] },
576
+ * { callbacks: [handler] },
577
+ * );
578
+ * ```
579
+ *
580
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
581
+ * @returns A BitfabLangGraphCallbackHandler configured for this client
582
+ */
583
+ getLangGraphCallbackHandler(traceFunctionKey: string): BitfabLangGraphCallbackHandler;
584
+ /**
585
+ * Get a Claude Agent SDK handler for tracing.
586
+ *
587
+ * The handler captures LLM turns, tool invocations, and subagent
588
+ * execution as Bitfab spans with proper parent-child hierarchy.
589
+ *
590
+ * ```typescript
591
+ * const handler = client.getClaudeAgentHandler("my-agent");
592
+ * const options = handler.instrumentOptions({
593
+ * model: "claude-sonnet-4-5-...",
594
+ * });
595
+ * const sdkClient = new ClaudeSDKClient(options);
596
+ * await sdkClient.connect();
597
+ * await sdkClient.query("Do something");
598
+ * for await (const msg of handler.wrapResponse(sdkClient.receiveResponse())) {
599
+ * // process messages
600
+ * }
601
+ * ```
602
+ *
603
+ * @param traceFunctionKey - Groups traces under this key in Bitfab
604
+ * @returns A BitfabClaudeAgentHandler configured for this client
605
+ */
606
+ getClaudeAgentHandler(traceFunctionKey: string): BitfabClaudeAgentHandler;
340
607
  /**
341
608
  * Wrap a BAML client method to automatically capture prompt and LLM metadata.
342
609
  *
@@ -447,16 +714,7 @@ declare class Bitfab {
447
714
  limit?: number;
448
715
  traceIds?: string[];
449
716
  maxConcurrency?: number;
450
- }): Promise<{
451
- items: Array<{
452
- input: unknown[];
453
- result: TReturn | undefined;
454
- originalOutput: unknown;
455
- error: string | null;
456
- }>;
457
- testRunId: string;
458
- testRunUrl: string;
459
- }>;
717
+ }): Promise<ReplayResult<TReturn>>;
460
718
  }
461
719
  /**
462
720
  * Represents a Bitfab function that can wrap user functions for tracing.
@@ -519,7 +777,7 @@ declare class BitfabFunction {
519
777
  /**
520
778
  * SDK version from package.json (injected at build time)
521
779
  */
522
- declare const __version__ = "0.9.2";
780
+ declare const __version__ = "0.11.4";
523
781
 
524
782
  /**
525
783
  * Constants for the Bitfab SDK.
@@ -529,40 +787,4 @@ declare const __version__ = "0.9.2";
529
787
  */
530
788
  declare const DEFAULT_SERVICE_URL = "https://bitfab.ai";
531
789
 
532
- /**
533
- * Replay historical traces through a function and create a test run.
534
- *
535
- * The replay flow has three phases:
536
- * 1. Start — fetches historical traces from the server and creates a test run
537
- * 2. Execute — re-runs each trace's inputs through the provided function locally
538
- * 3. Complete — marks the test run as completed on the server
539
- */
540
-
541
- interface ReplayOptions {
542
- /** Maximum number of traces to replay (1–100, default 5). */
543
- limit?: number;
544
- /** Optional list of specific trace IDs to replay. */
545
- traceIds?: string[];
546
- /** Maximum number of items to process in parallel. Set to 1 for sequential. Default 10. */
547
- maxConcurrency?: number;
548
- }
549
- interface ReplayItem<T> {
550
- /** Deserialized inputs from the original trace. */
551
- input: unknown[];
552
- /** The result returned by the function during replay, or undefined on error. */
553
- result: T | undefined;
554
- /** The original output from the historical trace. */
555
- originalOutput: unknown;
556
- /** Error message if the function threw, or null on success. */
557
- error: string | null;
558
- }
559
- interface ReplayResult<T> {
560
- /** Individual replay items with inputs, results, and comparison data. */
561
- items: ReplayItem<T>[];
562
- /** The test run ID created on the server. */
563
- testRunId: string;
564
- /** Full URL to view the test run in the dashboard. */
565
- testRunUrl: string;
566
- }
567
-
568
- export { type ActiveSpanContext, type AllowedEnvVars, type BamlExecutionResult, Bitfab, type BitfabConfig, BitfabError, BitfabFunction, BitfabOpenAITracingProcessor, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type ProviderDefinition, type ReplayItem, type ReplayOptions, type ReplayResult, type SpanOptions, type SpanType, type TraceResponse, type TracingProcessor, type WrapBAMLOptions, type WrappedBamlFn, __version__, flushTraces, getCurrentSpan, getCurrentTrace };
790
+ export { type ActiveSpanContext, type AllowedEnvVars, type BamlExecutionResult, Bitfab, BitfabClaudeAgentHandler, type BitfabConfig, BitfabError, BitfabFunction, BitfabLangGraphCallbackHandler, BitfabOpenAITracingProcessor, type CurrentSpan, type CurrentTrace, DEFAULT_SERVICE_URL, type ProviderDefinition, type ReplayItem, type ReplayOptions, type ReplayResult, type SpanOptions, type SpanType, type TokenUsage, type TraceResponse, type TracingProcessor, type WrapBAMLOptions, type WrappedBamlFn, __version__, flushTraces, getCurrentSpan, getCurrentTrace };