@bitfab/sdk 0.21.1 → 0.22.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/{chunk-75LZO6JS.js → chunk-4SLFC266.js} +154 -24
- package/dist/chunk-4SLFC266.js.map +1 -0
- package/dist/index.cjs +154 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -20
- package/dist/index.d.ts +141 -20
- package/dist/index.js +3 -1
- package/dist/node.cjs +154 -23
- 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 +1 -1
- package/dist/chunk-75LZO6JS.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -477,6 +477,7 @@ __export(index_exports, {
|
|
|
477
477
|
BitfabFunction: () => BitfabFunction,
|
|
478
478
|
BitfabLangChainCallbackHandler: () => BitfabLangGraphCallbackHandler,
|
|
479
479
|
BitfabLangGraphCallbackHandler: () => BitfabLangGraphCallbackHandler,
|
|
480
|
+
BitfabOpenAIAgentHandler: () => BitfabOpenAIAgentHandler,
|
|
480
481
|
BitfabOpenAITracingProcessor: () => BitfabOpenAITracingProcessor,
|
|
481
482
|
DEFAULT_SERVICE_URL: () => DEFAULT_SERVICE_URL,
|
|
482
483
|
ReplayEnvironment: () => ReplayEnvironment,
|
|
@@ -490,7 +491,7 @@ __export(index_exports, {
|
|
|
490
491
|
module.exports = __toCommonJS(index_exports);
|
|
491
492
|
|
|
492
493
|
// src/version.generated.ts
|
|
493
|
-
var __version__ = "0.
|
|
494
|
+
var __version__ = "0.22.0";
|
|
494
495
|
|
|
495
496
|
// src/constants.ts
|
|
496
497
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -961,6 +962,13 @@ var BitfabClaudeAgentHandler = class {
|
|
|
961
962
|
this.currentLlmHistorySnapshot = [];
|
|
962
963
|
// Subagent tracking
|
|
963
964
|
this.activeSubagentSpans = /* @__PURE__ */ new Map();
|
|
965
|
+
// Synthetic root span (handler-only replay). When an `input` is supplied to
|
|
966
|
+
// wrapQuery/wrapResponse, the handler emits a root `agent` span carrying that
|
|
967
|
+
// input, so a handler-instrumented run is replayable WITHOUT an enclosing
|
|
968
|
+
// withSpan — matching the LangGraph handler, which records the graph input as
|
|
969
|
+
// its root. The prompt is not present anywhere in the message stream, so it
|
|
970
|
+
// must be handed in explicitly.
|
|
971
|
+
this.hasRootInput = false;
|
|
964
972
|
this.httpClient = new HttpClient({
|
|
965
973
|
apiKey: config.apiKey,
|
|
966
974
|
serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,
|
|
@@ -995,7 +1003,30 @@ var BitfabClaudeAgentHandler = class {
|
|
|
995
1003
|
return subagentSpanId;
|
|
996
1004
|
}
|
|
997
1005
|
}
|
|
998
|
-
return this.
|
|
1006
|
+
return this.rootSpanId ?? this.activeContext?.spanId ?? null;
|
|
1007
|
+
}
|
|
1008
|
+
// Emit the synthetic root `agent` span once, before any child spans. No-op
|
|
1009
|
+
// unless an `input` was supplied AND there is no enclosing withSpan (in which
|
|
1010
|
+
// case that outer span is already the replayable root).
|
|
1011
|
+
maybeStartRootSpan() {
|
|
1012
|
+
if (!this.hasRootInput || this.rootSpanId !== null) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
this.ensureTrace();
|
|
1016
|
+
if (this.activeContext !== null) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
const spanId = crypto.randomUUID();
|
|
1020
|
+
this.startSpan(spanId, this.traceFunctionKey, "agent", this.rootInput, null);
|
|
1021
|
+
this.rootSpanId = spanId;
|
|
1022
|
+
}
|
|
1023
|
+
completeRootSpan() {
|
|
1024
|
+
if (this.rootSpanId === null) {
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
const spanId = this.rootSpanId;
|
|
1028
|
+
this.rootSpanId = null;
|
|
1029
|
+
this.completeSpan(spanId, this.rootOutput);
|
|
999
1030
|
}
|
|
1000
1031
|
// ── span helpers ─────────────────────────────────────────────
|
|
1001
1032
|
startSpan(spanId, name, spanType, inputData, parentId) {
|
|
@@ -1191,26 +1222,53 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1191
1222
|
return options;
|
|
1192
1223
|
}
|
|
1193
1224
|
/**
|
|
1194
|
-
* Wrap
|
|
1225
|
+
* Wrap any Claude Agent SDK message stream to capture LLM turns.
|
|
1226
|
+
*
|
|
1227
|
+
* Yields every message unchanged while capturing assistant message
|
|
1228
|
+
* content as LLM turn spans. Kept for naming symmetry with the Python
|
|
1229
|
+
* SDK's `wrapResponse` (which wraps `ClaudeSDKClient.receiveResponse()`);
|
|
1230
|
+
* in TypeScript, prefer `wrapQuery` around `query()`.
|
|
1195
1231
|
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1232
|
+
* Pass `{ input }` (the prompt) to record a replayable root span — see
|
|
1233
|
+
* `wrapQuery`.
|
|
1198
1234
|
*/
|
|
1199
|
-
async *wrapResponse(stream) {
|
|
1235
|
+
async *wrapResponse(stream, opts) {
|
|
1236
|
+
this.setRootInput(opts);
|
|
1200
1237
|
yield* this.processStream(stream);
|
|
1201
1238
|
}
|
|
1202
1239
|
/**
|
|
1203
1240
|
* Wrap a `query()` async iterator to capture LLM turns.
|
|
1204
1241
|
*
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1242
|
+
* Tool and subagent spans are captured separately via the hooks injected
|
|
1243
|
+
* by `instrumentOptions` into the `options` passed to `query()`.
|
|
1244
|
+
*
|
|
1245
|
+
* Pass `{ input }` — the prompt (or the serializable args that produced it)
|
|
1246
|
+
* — to make a handler-only run replayable: the handler records a root `agent`
|
|
1247
|
+
* span with that input, so `replay(key, fn)` can re-feed it. Omit it only
|
|
1248
|
+
* when an enclosing `withSpan` already supplies the replayable root.
|
|
1249
|
+
*
|
|
1250
|
+
* ```typescript
|
|
1251
|
+
* handler.wrapQuery(query({ prompt, options }), { input: prompt })
|
|
1252
|
+
* ```
|
|
1207
1253
|
*/
|
|
1208
|
-
async *wrapQuery(stream) {
|
|
1254
|
+
async *wrapQuery(stream, opts) {
|
|
1255
|
+
this.setRootInput(opts);
|
|
1209
1256
|
yield* this.processStream(stream);
|
|
1210
1257
|
}
|
|
1258
|
+
setRootInput(opts) {
|
|
1259
|
+
if (opts && opts.input !== void 0) {
|
|
1260
|
+
this.hasRootInput = true;
|
|
1261
|
+
this.rootInput = opts.input;
|
|
1262
|
+
} else {
|
|
1263
|
+
this.hasRootInput = false;
|
|
1264
|
+
this.rootInput = void 0;
|
|
1265
|
+
}
|
|
1266
|
+
this.rootOutput = void 0;
|
|
1267
|
+
}
|
|
1211
1268
|
// ── stream processing ────────────────────────────────────────
|
|
1212
1269
|
async *processStream(stream) {
|
|
1213
1270
|
try {
|
|
1271
|
+
this.maybeStartRootSpan();
|
|
1214
1272
|
for await (const message of stream) {
|
|
1215
1273
|
try {
|
|
1216
1274
|
this.processMessage(message);
|
|
@@ -1221,6 +1279,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1221
1279
|
} finally {
|
|
1222
1280
|
try {
|
|
1223
1281
|
this.flushLlmTurn();
|
|
1282
|
+
this.completeRootSpan();
|
|
1224
1283
|
this.sendTraceCompletion();
|
|
1225
1284
|
} catch {
|
|
1226
1285
|
}
|
|
@@ -1228,18 +1287,19 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1228
1287
|
}
|
|
1229
1288
|
}
|
|
1230
1289
|
processMessage(message) {
|
|
1231
|
-
const typeName = message.
|
|
1232
|
-
if (typeName === "
|
|
1290
|
+
const typeName = message.type;
|
|
1291
|
+
if (typeName === "assistant") {
|
|
1233
1292
|
this.handleAssistantMessage(message);
|
|
1234
|
-
} else if (typeName === "
|
|
1293
|
+
} else if (typeName === "user") {
|
|
1235
1294
|
this.handleUserMessage(message);
|
|
1236
|
-
} else if (typeName === "
|
|
1295
|
+
} else if (typeName === "result") {
|
|
1237
1296
|
this.handleResultMessage(message);
|
|
1238
1297
|
}
|
|
1239
1298
|
}
|
|
1240
1299
|
handleAssistantMessage(message) {
|
|
1241
1300
|
this.ensureTrace();
|
|
1242
|
-
const
|
|
1301
|
+
const inner = message.message ?? {};
|
|
1302
|
+
const messageId = inner.id ?? message.uuid;
|
|
1243
1303
|
if (messageId !== this.currentLlmMessageId) {
|
|
1244
1304
|
this.flushLlmTurn();
|
|
1245
1305
|
this.conversationHistory.push(...this.pendingMessages);
|
|
@@ -1247,26 +1307,27 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1247
1307
|
this.currentLlmSpanId = crypto.randomUUID();
|
|
1248
1308
|
this.currentLlmMessageId = messageId ?? null;
|
|
1249
1309
|
this.currentLlmContent = [];
|
|
1250
|
-
this.currentLlmModel =
|
|
1310
|
+
this.currentLlmModel = inner.model ?? null;
|
|
1251
1311
|
this.currentLlmUsage = {};
|
|
1252
1312
|
this.currentLlmStartedAt = nowIso();
|
|
1253
1313
|
this.currentLlmHistorySnapshot = [...this.conversationHistory];
|
|
1254
1314
|
}
|
|
1255
|
-
const content =
|
|
1315
|
+
const content = inner.content;
|
|
1256
1316
|
if (Array.isArray(content)) {
|
|
1257
1317
|
this.currentLlmContent.push(...extractContentBlocks(content));
|
|
1258
1318
|
}
|
|
1259
|
-
const usage = extractUsage(
|
|
1319
|
+
const usage = extractUsage(inner);
|
|
1260
1320
|
if (Object.keys(usage).length > 0) {
|
|
1261
1321
|
Object.assign(this.currentLlmUsage, usage);
|
|
1262
1322
|
}
|
|
1263
|
-
const model =
|
|
1323
|
+
const model = inner.model;
|
|
1264
1324
|
if (model) {
|
|
1265
1325
|
this.currentLlmModel = model;
|
|
1266
1326
|
}
|
|
1267
1327
|
}
|
|
1268
1328
|
handleUserMessage(message) {
|
|
1269
|
-
const
|
|
1329
|
+
const inner = message.message ?? {};
|
|
1330
|
+
const content = inner.content;
|
|
1270
1331
|
const toolUseResult = message.tool_use_result;
|
|
1271
1332
|
if (toolUseResult !== void 0) {
|
|
1272
1333
|
this.pendingMessages.push({
|
|
@@ -1283,6 +1344,10 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1283
1344
|
}
|
|
1284
1345
|
handleResultMessage(message) {
|
|
1285
1346
|
this.flushLlmTurn();
|
|
1347
|
+
if (message.result !== void 0) {
|
|
1348
|
+
this.rootOutput = message.result;
|
|
1349
|
+
}
|
|
1350
|
+
this.completeRootSpan();
|
|
1286
1351
|
const metadata = {};
|
|
1287
1352
|
for (const attr of [
|
|
1288
1353
|
"num_turns",
|
|
@@ -1346,6 +1411,9 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1346
1411
|
this.runToSpan.clear();
|
|
1347
1412
|
this.traceId = null;
|
|
1348
1413
|
this.rootSpanId = null;
|
|
1414
|
+
this.hasRootInput = false;
|
|
1415
|
+
this.rootInput = void 0;
|
|
1416
|
+
this.rootOutput = void 0;
|
|
1349
1417
|
this.activeContext = null;
|
|
1350
1418
|
this.traceStartedAt = null;
|
|
1351
1419
|
this.conversationHistory = [];
|
|
@@ -2205,6 +2273,39 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2205
2273
|
}
|
|
2206
2274
|
};
|
|
2207
2275
|
|
|
2276
|
+
// src/openaiAgentSdk.ts
|
|
2277
|
+
var BitfabOpenAIAgentHandler = class {
|
|
2278
|
+
constructor(config) {
|
|
2279
|
+
this.traceFunctionKey = config.traceFunctionKey;
|
|
2280
|
+
this.withSpanFn = config.withSpan;
|
|
2281
|
+
}
|
|
2282
|
+
async wrapRun(agent, input, options) {
|
|
2283
|
+
const { run } = await import("@openai/agents");
|
|
2284
|
+
const isStreaming = options?.stream === true;
|
|
2285
|
+
const finalize = async (result) => {
|
|
2286
|
+
const res = result;
|
|
2287
|
+
if (isStreaming && res?.completed) {
|
|
2288
|
+
try {
|
|
2289
|
+
await res.completed;
|
|
2290
|
+
} catch {
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
return res?.finalOutput;
|
|
2294
|
+
};
|
|
2295
|
+
const options_ = { type: "agent", finalize };
|
|
2296
|
+
const traced = this.withSpanFn(
|
|
2297
|
+
this.traceFunctionKey,
|
|
2298
|
+
options_,
|
|
2299
|
+
(agentInput) => run(
|
|
2300
|
+
agent,
|
|
2301
|
+
agentInput,
|
|
2302
|
+
options
|
|
2303
|
+
)
|
|
2304
|
+
);
|
|
2305
|
+
return traced(input);
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
|
|
2208
2309
|
// src/client.ts
|
|
2209
2310
|
init_replayContext();
|
|
2210
2311
|
|
|
@@ -2898,6 +2999,34 @@ var Bitfab = class {
|
|
|
2898
2999
|
}
|
|
2899
3000
|
});
|
|
2900
3001
|
}
|
|
3002
|
+
/**
|
|
3003
|
+
* Get an OpenAI Agents SDK handler that records a replayable root span.
|
|
3004
|
+
*
|
|
3005
|
+
* The processor from {@link getOpenAiTracingProcessor} captures everything
|
|
3006
|
+
* inside a run (LLM calls, tools, handoffs) but never sees the caller's
|
|
3007
|
+
* input, so a processor-only run records an empty-input root and is not
|
|
3008
|
+
* replayable. This handler's `wrapRun` is a drop-in for `run()` that opens a
|
|
3009
|
+
* `withSpan` root carrying the input and final output; the processor's spans
|
|
3010
|
+
* nest beneath it. Register the processor once at startup, then call
|
|
3011
|
+
* `handler.wrapRun(agent, input)` in place of `run(agent, input)`.
|
|
3012
|
+
*
|
|
3013
|
+
* ```typescript
|
|
3014
|
+
* import { addTraceProcessor, Agent, run } from "@openai/agents";
|
|
3015
|
+
*
|
|
3016
|
+
* addTraceProcessor(client.getOpenAiTracingProcessor());
|
|
3017
|
+
* const handler = client.getOpenAiAgentHandler("research-topic");
|
|
3018
|
+
* const result = await handler.wrapRun(agent, "Find X");
|
|
3019
|
+
* ```
|
|
3020
|
+
*
|
|
3021
|
+
* @param traceFunctionKey - Groups traces under this key in Bitfab
|
|
3022
|
+
* @returns A BitfabOpenAIAgentHandler configured for this client
|
|
3023
|
+
*/
|
|
3024
|
+
getOpenAiAgentHandler(traceFunctionKey) {
|
|
3025
|
+
return new BitfabOpenAIAgentHandler({
|
|
3026
|
+
traceFunctionKey,
|
|
3027
|
+
withSpan: this.withSpan.bind(this)
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
2901
3030
|
/**
|
|
2902
3031
|
* Get a LangGraph/LangChain callback handler for tracing.
|
|
2903
3032
|
*
|
|
@@ -2951,14 +3080,15 @@ var Bitfab = class {
|
|
|
2951
3080
|
* execution as Bitfab spans with proper parent-child hierarchy.
|
|
2952
3081
|
*
|
|
2953
3082
|
* ```typescript
|
|
3083
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
3084
|
+
*
|
|
2954
3085
|
* const handler = client.getClaudeAgentHandler("my-agent");
|
|
2955
3086
|
* const options = handler.instrumentOptions({
|
|
2956
3087
|
* model: "claude-sonnet-4-5-...",
|
|
2957
3088
|
* });
|
|
2958
|
-
* const
|
|
2959
|
-
*
|
|
2960
|
-
*
|
|
2961
|
-
* for await (const msg of handler.wrapResponse(sdkClient.receiveResponse())) {
|
|
3089
|
+
* for await (const msg of handler.wrapQuery(
|
|
3090
|
+
* query({ prompt: "Do something", options })
|
|
3091
|
+
* )) {
|
|
2962
3092
|
* // process messages
|
|
2963
3093
|
* }
|
|
2964
3094
|
* ```
|
|
@@ -3647,6 +3777,7 @@ var finalizers = {
|
|
|
3647
3777
|
BitfabFunction,
|
|
3648
3778
|
BitfabLangChainCallbackHandler,
|
|
3649
3779
|
BitfabLangGraphCallbackHandler,
|
|
3780
|
+
BitfabOpenAIAgentHandler,
|
|
3650
3781
|
BitfabOpenAITracingProcessor,
|
|
3651
3782
|
DEFAULT_SERVICE_URL,
|
|
3652
3783
|
ReplayEnvironment,
|