@bitfab/sdk 0.21.0 → 0.21.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-UO3CIQ7R.js → chunk-3YKMCCDV.js} +103 -26
- package/dist/chunk-3YKMCCDV.js.map +1 -0
- package/dist/index.cjs +102 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -18
- package/dist/index.d.ts +46 -18
- package/dist/index.js +1 -1
- package/dist/node.cjs +102 -25
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-UO3CIQ7R.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -490,7 +490,7 @@ __export(index_exports, {
|
|
|
490
490
|
module.exports = __toCommonJS(index_exports);
|
|
491
491
|
|
|
492
492
|
// src/version.generated.ts
|
|
493
|
-
var __version__ = "0.21.
|
|
493
|
+
var __version__ = "0.21.2";
|
|
494
494
|
|
|
495
495
|
// src/constants.ts
|
|
496
496
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -961,6 +961,13 @@ var BitfabClaudeAgentHandler = class {
|
|
|
961
961
|
this.currentLlmHistorySnapshot = [];
|
|
962
962
|
// Subagent tracking
|
|
963
963
|
this.activeSubagentSpans = /* @__PURE__ */ new Map();
|
|
964
|
+
// Synthetic root span (handler-only replay). When an `input` is supplied to
|
|
965
|
+
// wrapQuery/wrapResponse, the handler emits a root `agent` span carrying that
|
|
966
|
+
// input, so a handler-instrumented run is replayable WITHOUT an enclosing
|
|
967
|
+
// withSpan — matching the LangGraph handler, which records the graph input as
|
|
968
|
+
// its root. The prompt is not present anywhere in the message stream, so it
|
|
969
|
+
// must be handed in explicitly.
|
|
970
|
+
this.hasRootInput = false;
|
|
964
971
|
this.httpClient = new HttpClient({
|
|
965
972
|
apiKey: config.apiKey,
|
|
966
973
|
serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,
|
|
@@ -995,7 +1002,30 @@ var BitfabClaudeAgentHandler = class {
|
|
|
995
1002
|
return subagentSpanId;
|
|
996
1003
|
}
|
|
997
1004
|
}
|
|
998
|
-
return this.
|
|
1005
|
+
return this.rootSpanId ?? this.activeContext?.spanId ?? null;
|
|
1006
|
+
}
|
|
1007
|
+
// Emit the synthetic root `agent` span once, before any child spans. No-op
|
|
1008
|
+
// unless an `input` was supplied AND there is no enclosing withSpan (in which
|
|
1009
|
+
// case that outer span is already the replayable root).
|
|
1010
|
+
maybeStartRootSpan() {
|
|
1011
|
+
if (!this.hasRootInput || this.rootSpanId !== null) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
this.ensureTrace();
|
|
1015
|
+
if (this.activeContext !== null) {
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
const spanId = crypto.randomUUID();
|
|
1019
|
+
this.startSpan(spanId, this.traceFunctionKey, "agent", this.rootInput, null);
|
|
1020
|
+
this.rootSpanId = spanId;
|
|
1021
|
+
}
|
|
1022
|
+
completeRootSpan() {
|
|
1023
|
+
if (this.rootSpanId === null) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
const spanId = this.rootSpanId;
|
|
1027
|
+
this.rootSpanId = null;
|
|
1028
|
+
this.completeSpan(spanId, this.rootOutput);
|
|
999
1029
|
}
|
|
1000
1030
|
// ── span helpers ─────────────────────────────────────────────
|
|
1001
1031
|
startSpan(spanId, name, spanType, inputData, parentId) {
|
|
@@ -1191,26 +1221,53 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1191
1221
|
return options;
|
|
1192
1222
|
}
|
|
1193
1223
|
/**
|
|
1194
|
-
* Wrap
|
|
1224
|
+
* Wrap any Claude Agent SDK message stream to capture LLM turns.
|
|
1225
|
+
*
|
|
1226
|
+
* Yields every message unchanged while capturing assistant message
|
|
1227
|
+
* content as LLM turn spans. Kept for naming symmetry with the Python
|
|
1228
|
+
* SDK's `wrapResponse` (which wraps `ClaudeSDKClient.receiveResponse()`);
|
|
1229
|
+
* in TypeScript, prefer `wrapQuery` around `query()`.
|
|
1195
1230
|
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1231
|
+
* Pass `{ input }` (the prompt) to record a replayable root span — see
|
|
1232
|
+
* `wrapQuery`.
|
|
1198
1233
|
*/
|
|
1199
|
-
async *wrapResponse(stream) {
|
|
1234
|
+
async *wrapResponse(stream, opts) {
|
|
1235
|
+
this.setRootInput(opts);
|
|
1200
1236
|
yield* this.processStream(stream);
|
|
1201
1237
|
}
|
|
1202
1238
|
/**
|
|
1203
1239
|
* Wrap a `query()` async iterator to capture LLM turns.
|
|
1204
1240
|
*
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1241
|
+
* Tool and subagent spans are captured separately via the hooks injected
|
|
1242
|
+
* by `instrumentOptions` into the `options` passed to `query()`.
|
|
1243
|
+
*
|
|
1244
|
+
* Pass `{ input }` — the prompt (or the serializable args that produced it)
|
|
1245
|
+
* — to make a handler-only run replayable: the handler records a root `agent`
|
|
1246
|
+
* span with that input, so `replay(key, fn)` can re-feed it. Omit it only
|
|
1247
|
+
* when an enclosing `withSpan` already supplies the replayable root.
|
|
1248
|
+
*
|
|
1249
|
+
* ```typescript
|
|
1250
|
+
* handler.wrapQuery(query({ prompt, options }), { input: prompt })
|
|
1251
|
+
* ```
|
|
1207
1252
|
*/
|
|
1208
|
-
async *wrapQuery(stream) {
|
|
1253
|
+
async *wrapQuery(stream, opts) {
|
|
1254
|
+
this.setRootInput(opts);
|
|
1209
1255
|
yield* this.processStream(stream);
|
|
1210
1256
|
}
|
|
1257
|
+
setRootInput(opts) {
|
|
1258
|
+
if (opts && opts.input !== void 0) {
|
|
1259
|
+
this.hasRootInput = true;
|
|
1260
|
+
this.rootInput = opts.input;
|
|
1261
|
+
} else {
|
|
1262
|
+
this.hasRootInput = false;
|
|
1263
|
+
this.rootInput = void 0;
|
|
1264
|
+
}
|
|
1265
|
+
this.rootOutput = void 0;
|
|
1266
|
+
}
|
|
1211
1267
|
// ── stream processing ────────────────────────────────────────
|
|
1212
1268
|
async *processStream(stream) {
|
|
1213
1269
|
try {
|
|
1270
|
+
this.maybeStartRootSpan();
|
|
1214
1271
|
for await (const message of stream) {
|
|
1215
1272
|
try {
|
|
1216
1273
|
this.processMessage(message);
|
|
@@ -1221,6 +1278,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1221
1278
|
} finally {
|
|
1222
1279
|
try {
|
|
1223
1280
|
this.flushLlmTurn();
|
|
1281
|
+
this.completeRootSpan();
|
|
1224
1282
|
this.sendTraceCompletion();
|
|
1225
1283
|
} catch {
|
|
1226
1284
|
}
|
|
@@ -1228,18 +1286,19 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1228
1286
|
}
|
|
1229
1287
|
}
|
|
1230
1288
|
processMessage(message) {
|
|
1231
|
-
const typeName = message.
|
|
1232
|
-
if (typeName === "
|
|
1289
|
+
const typeName = message.type;
|
|
1290
|
+
if (typeName === "assistant") {
|
|
1233
1291
|
this.handleAssistantMessage(message);
|
|
1234
|
-
} else if (typeName === "
|
|
1292
|
+
} else if (typeName === "user") {
|
|
1235
1293
|
this.handleUserMessage(message);
|
|
1236
|
-
} else if (typeName === "
|
|
1294
|
+
} else if (typeName === "result") {
|
|
1237
1295
|
this.handleResultMessage(message);
|
|
1238
1296
|
}
|
|
1239
1297
|
}
|
|
1240
1298
|
handleAssistantMessage(message) {
|
|
1241
1299
|
this.ensureTrace();
|
|
1242
|
-
const
|
|
1300
|
+
const inner = message.message ?? {};
|
|
1301
|
+
const messageId = inner.id ?? message.uuid;
|
|
1243
1302
|
if (messageId !== this.currentLlmMessageId) {
|
|
1244
1303
|
this.flushLlmTurn();
|
|
1245
1304
|
this.conversationHistory.push(...this.pendingMessages);
|
|
@@ -1247,26 +1306,27 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1247
1306
|
this.currentLlmSpanId = crypto.randomUUID();
|
|
1248
1307
|
this.currentLlmMessageId = messageId ?? null;
|
|
1249
1308
|
this.currentLlmContent = [];
|
|
1250
|
-
this.currentLlmModel =
|
|
1309
|
+
this.currentLlmModel = inner.model ?? null;
|
|
1251
1310
|
this.currentLlmUsage = {};
|
|
1252
1311
|
this.currentLlmStartedAt = nowIso();
|
|
1253
1312
|
this.currentLlmHistorySnapshot = [...this.conversationHistory];
|
|
1254
1313
|
}
|
|
1255
|
-
const content =
|
|
1314
|
+
const content = inner.content;
|
|
1256
1315
|
if (Array.isArray(content)) {
|
|
1257
1316
|
this.currentLlmContent.push(...extractContentBlocks(content));
|
|
1258
1317
|
}
|
|
1259
|
-
const usage = extractUsage(
|
|
1318
|
+
const usage = extractUsage(inner);
|
|
1260
1319
|
if (Object.keys(usage).length > 0) {
|
|
1261
1320
|
Object.assign(this.currentLlmUsage, usage);
|
|
1262
1321
|
}
|
|
1263
|
-
const model =
|
|
1322
|
+
const model = inner.model;
|
|
1264
1323
|
if (model) {
|
|
1265
1324
|
this.currentLlmModel = model;
|
|
1266
1325
|
}
|
|
1267
1326
|
}
|
|
1268
1327
|
handleUserMessage(message) {
|
|
1269
|
-
const
|
|
1328
|
+
const inner = message.message ?? {};
|
|
1329
|
+
const content = inner.content;
|
|
1270
1330
|
const toolUseResult = message.tool_use_result;
|
|
1271
1331
|
if (toolUseResult !== void 0) {
|
|
1272
1332
|
this.pendingMessages.push({
|
|
@@ -1283,6 +1343,10 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1283
1343
|
}
|
|
1284
1344
|
handleResultMessage(message) {
|
|
1285
1345
|
this.flushLlmTurn();
|
|
1346
|
+
if (message.result !== void 0) {
|
|
1347
|
+
this.rootOutput = message.result;
|
|
1348
|
+
}
|
|
1349
|
+
this.completeRootSpan();
|
|
1286
1350
|
const metadata = {};
|
|
1287
1351
|
for (const attr of [
|
|
1288
1352
|
"num_turns",
|
|
@@ -1346,6 +1410,9 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1346
1410
|
this.runToSpan.clear();
|
|
1347
1411
|
this.traceId = null;
|
|
1348
1412
|
this.rootSpanId = null;
|
|
1413
|
+
this.hasRootInput = false;
|
|
1414
|
+
this.rootInput = void 0;
|
|
1415
|
+
this.rootOutput = void 0;
|
|
1349
1416
|
this.activeContext = null;
|
|
1350
1417
|
this.traceStartedAt = null;
|
|
1351
1418
|
this.conversationHistory = [];
|
|
@@ -2423,9 +2490,15 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2423
2490
|
* Extract and add input/response to serialized span, updating errors list.
|
|
2424
2491
|
*/
|
|
2425
2492
|
extractSpanInputResponse(span, serializedSpan, errors) {
|
|
2493
|
+
if (span.spanData?.type !== "response") {
|
|
2494
|
+
return;
|
|
2495
|
+
}
|
|
2426
2496
|
const spanData = serializedSpan.span_data;
|
|
2427
2497
|
try {
|
|
2428
|
-
|
|
2498
|
+
const input = span.spanData?._input;
|
|
2499
|
+
if (input !== void 0) {
|
|
2500
|
+
spanData.input = input;
|
|
2501
|
+
}
|
|
2429
2502
|
} catch (error) {
|
|
2430
2503
|
errors.push({
|
|
2431
2504
|
source: "sdk",
|
|
@@ -2434,7 +2507,10 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2434
2507
|
});
|
|
2435
2508
|
}
|
|
2436
2509
|
try {
|
|
2437
|
-
|
|
2510
|
+
const response = span.spanData?._response;
|
|
2511
|
+
if (response !== void 0) {
|
|
2512
|
+
spanData.response = response;
|
|
2513
|
+
}
|
|
2438
2514
|
} catch (error) {
|
|
2439
2515
|
errors.push({
|
|
2440
2516
|
source: "sdk",
|
|
@@ -2942,14 +3018,15 @@ var Bitfab = class {
|
|
|
2942
3018
|
* execution as Bitfab spans with proper parent-child hierarchy.
|
|
2943
3019
|
*
|
|
2944
3020
|
* ```typescript
|
|
3021
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
3022
|
+
*
|
|
2945
3023
|
* const handler = client.getClaudeAgentHandler("my-agent");
|
|
2946
3024
|
* const options = handler.instrumentOptions({
|
|
2947
3025
|
* model: "claude-sonnet-4-5-...",
|
|
2948
3026
|
* });
|
|
2949
|
-
* const
|
|
2950
|
-
*
|
|
2951
|
-
*
|
|
2952
|
-
* for await (const msg of handler.wrapResponse(sdkClient.receiveResponse())) {
|
|
3027
|
+
* for await (const msg of handler.wrapQuery(
|
|
3028
|
+
* query({ prompt: "Do something", options })
|
|
3029
|
+
* )) {
|
|
2953
3030
|
* // process messages
|
|
2954
3031
|
* }
|
|
2955
3032
|
* ```
|