bitfab 0.21.1 → 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-75LZO6JS.js → chunk-3YKMCCDV.js} +92 -24
- package/dist/chunk-3YKMCCDV.js.map +1 -0
- package/dist/index.cjs +91 -23
- 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 +91 -23
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-75LZO6JS.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -499,7 +499,7 @@ __export(index_exports, {
|
|
|
499
499
|
module.exports = __toCommonJS(index_exports);
|
|
500
500
|
|
|
501
501
|
// src/version.generated.ts
|
|
502
|
-
var __version__ = "0.21.
|
|
502
|
+
var __version__ = "0.21.2";
|
|
503
503
|
|
|
504
504
|
// src/constants.ts
|
|
505
505
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -970,6 +970,13 @@ var BitfabClaudeAgentHandler = class {
|
|
|
970
970
|
this.currentLlmHistorySnapshot = [];
|
|
971
971
|
// Subagent tracking
|
|
972
972
|
this.activeSubagentSpans = /* @__PURE__ */ new Map();
|
|
973
|
+
// Synthetic root span (handler-only replay). When an `input` is supplied to
|
|
974
|
+
// wrapQuery/wrapResponse, the handler emits a root `agent` span carrying that
|
|
975
|
+
// input, so a handler-instrumented run is replayable WITHOUT an enclosing
|
|
976
|
+
// withSpan — matching the LangGraph handler, which records the graph input as
|
|
977
|
+
// its root. The prompt is not present anywhere in the message stream, so it
|
|
978
|
+
// must be handed in explicitly.
|
|
979
|
+
this.hasRootInput = false;
|
|
973
980
|
this.httpClient = new HttpClient({
|
|
974
981
|
apiKey: config.apiKey,
|
|
975
982
|
serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,
|
|
@@ -1004,7 +1011,30 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1004
1011
|
return subagentSpanId;
|
|
1005
1012
|
}
|
|
1006
1013
|
}
|
|
1007
|
-
return this.
|
|
1014
|
+
return this.rootSpanId ?? this.activeContext?.spanId ?? null;
|
|
1015
|
+
}
|
|
1016
|
+
// Emit the synthetic root `agent` span once, before any child spans. No-op
|
|
1017
|
+
// unless an `input` was supplied AND there is no enclosing withSpan (in which
|
|
1018
|
+
// case that outer span is already the replayable root).
|
|
1019
|
+
maybeStartRootSpan() {
|
|
1020
|
+
if (!this.hasRootInput || this.rootSpanId !== null) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
this.ensureTrace();
|
|
1024
|
+
if (this.activeContext !== null) {
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
const spanId = crypto.randomUUID();
|
|
1028
|
+
this.startSpan(spanId, this.traceFunctionKey, "agent", this.rootInput, null);
|
|
1029
|
+
this.rootSpanId = spanId;
|
|
1030
|
+
}
|
|
1031
|
+
completeRootSpan() {
|
|
1032
|
+
if (this.rootSpanId === null) {
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
const spanId = this.rootSpanId;
|
|
1036
|
+
this.rootSpanId = null;
|
|
1037
|
+
this.completeSpan(spanId, this.rootOutput);
|
|
1008
1038
|
}
|
|
1009
1039
|
// ── span helpers ─────────────────────────────────────────────
|
|
1010
1040
|
startSpan(spanId, name, spanType, inputData, parentId) {
|
|
@@ -1200,26 +1230,53 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1200
1230
|
return options;
|
|
1201
1231
|
}
|
|
1202
1232
|
/**
|
|
1203
|
-
* Wrap
|
|
1233
|
+
* Wrap any Claude Agent SDK message stream to capture LLM turns.
|
|
1204
1234
|
*
|
|
1205
|
-
* Yields every message unchanged while capturing
|
|
1206
|
-
* content as LLM turn spans.
|
|
1235
|
+
* Yields every message unchanged while capturing assistant message
|
|
1236
|
+
* content as LLM turn spans. Kept for naming symmetry with the Python
|
|
1237
|
+
* SDK's `wrapResponse` (which wraps `ClaudeSDKClient.receiveResponse()`);
|
|
1238
|
+
* in TypeScript, prefer `wrapQuery` around `query()`.
|
|
1239
|
+
*
|
|
1240
|
+
* Pass `{ input }` (the prompt) to record a replayable root span — see
|
|
1241
|
+
* `wrapQuery`.
|
|
1207
1242
|
*/
|
|
1208
|
-
async *wrapResponse(stream) {
|
|
1243
|
+
async *wrapResponse(stream, opts) {
|
|
1244
|
+
this.setRootInput(opts);
|
|
1209
1245
|
yield* this.processStream(stream);
|
|
1210
1246
|
}
|
|
1211
1247
|
/**
|
|
1212
1248
|
* Wrap a `query()` async iterator to capture LLM turns.
|
|
1213
1249
|
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1250
|
+
* Tool and subagent spans are captured separately via the hooks injected
|
|
1251
|
+
* by `instrumentOptions` into the `options` passed to `query()`.
|
|
1252
|
+
*
|
|
1253
|
+
* Pass `{ input }` — the prompt (or the serializable args that produced it)
|
|
1254
|
+
* — to make a handler-only run replayable: the handler records a root `agent`
|
|
1255
|
+
* span with that input, so `replay(key, fn)` can re-feed it. Omit it only
|
|
1256
|
+
* when an enclosing `withSpan` already supplies the replayable root.
|
|
1257
|
+
*
|
|
1258
|
+
* ```typescript
|
|
1259
|
+
* handler.wrapQuery(query({ prompt, options }), { input: prompt })
|
|
1260
|
+
* ```
|
|
1216
1261
|
*/
|
|
1217
|
-
async *wrapQuery(stream) {
|
|
1262
|
+
async *wrapQuery(stream, opts) {
|
|
1263
|
+
this.setRootInput(opts);
|
|
1218
1264
|
yield* this.processStream(stream);
|
|
1219
1265
|
}
|
|
1266
|
+
setRootInput(opts) {
|
|
1267
|
+
if (opts && opts.input !== void 0) {
|
|
1268
|
+
this.hasRootInput = true;
|
|
1269
|
+
this.rootInput = opts.input;
|
|
1270
|
+
} else {
|
|
1271
|
+
this.hasRootInput = false;
|
|
1272
|
+
this.rootInput = void 0;
|
|
1273
|
+
}
|
|
1274
|
+
this.rootOutput = void 0;
|
|
1275
|
+
}
|
|
1220
1276
|
// ── stream processing ────────────────────────────────────────
|
|
1221
1277
|
async *processStream(stream) {
|
|
1222
1278
|
try {
|
|
1279
|
+
this.maybeStartRootSpan();
|
|
1223
1280
|
for await (const message of stream) {
|
|
1224
1281
|
try {
|
|
1225
1282
|
this.processMessage(message);
|
|
@@ -1230,6 +1287,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1230
1287
|
} finally {
|
|
1231
1288
|
try {
|
|
1232
1289
|
this.flushLlmTurn();
|
|
1290
|
+
this.completeRootSpan();
|
|
1233
1291
|
this.sendTraceCompletion();
|
|
1234
1292
|
} catch {
|
|
1235
1293
|
}
|
|
@@ -1237,18 +1295,19 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1237
1295
|
}
|
|
1238
1296
|
}
|
|
1239
1297
|
processMessage(message) {
|
|
1240
|
-
const typeName = message.
|
|
1241
|
-
if (typeName === "
|
|
1298
|
+
const typeName = message.type;
|
|
1299
|
+
if (typeName === "assistant") {
|
|
1242
1300
|
this.handleAssistantMessage(message);
|
|
1243
|
-
} else if (typeName === "
|
|
1301
|
+
} else if (typeName === "user") {
|
|
1244
1302
|
this.handleUserMessage(message);
|
|
1245
|
-
} else if (typeName === "
|
|
1303
|
+
} else if (typeName === "result") {
|
|
1246
1304
|
this.handleResultMessage(message);
|
|
1247
1305
|
}
|
|
1248
1306
|
}
|
|
1249
1307
|
handleAssistantMessage(message) {
|
|
1250
1308
|
this.ensureTrace();
|
|
1251
|
-
const
|
|
1309
|
+
const inner = message.message ?? {};
|
|
1310
|
+
const messageId = inner.id ?? message.uuid;
|
|
1252
1311
|
if (messageId !== this.currentLlmMessageId) {
|
|
1253
1312
|
this.flushLlmTurn();
|
|
1254
1313
|
this.conversationHistory.push(...this.pendingMessages);
|
|
@@ -1256,26 +1315,27 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1256
1315
|
this.currentLlmSpanId = crypto.randomUUID();
|
|
1257
1316
|
this.currentLlmMessageId = messageId ?? null;
|
|
1258
1317
|
this.currentLlmContent = [];
|
|
1259
|
-
this.currentLlmModel =
|
|
1318
|
+
this.currentLlmModel = inner.model ?? null;
|
|
1260
1319
|
this.currentLlmUsage = {};
|
|
1261
1320
|
this.currentLlmStartedAt = nowIso();
|
|
1262
1321
|
this.currentLlmHistorySnapshot = [...this.conversationHistory];
|
|
1263
1322
|
}
|
|
1264
|
-
const content =
|
|
1323
|
+
const content = inner.content;
|
|
1265
1324
|
if (Array.isArray(content)) {
|
|
1266
1325
|
this.currentLlmContent.push(...extractContentBlocks(content));
|
|
1267
1326
|
}
|
|
1268
|
-
const usage = extractUsage(
|
|
1327
|
+
const usage = extractUsage(inner);
|
|
1269
1328
|
if (Object.keys(usage).length > 0) {
|
|
1270
1329
|
Object.assign(this.currentLlmUsage, usage);
|
|
1271
1330
|
}
|
|
1272
|
-
const model =
|
|
1331
|
+
const model = inner.model;
|
|
1273
1332
|
if (model) {
|
|
1274
1333
|
this.currentLlmModel = model;
|
|
1275
1334
|
}
|
|
1276
1335
|
}
|
|
1277
1336
|
handleUserMessage(message) {
|
|
1278
|
-
const
|
|
1337
|
+
const inner = message.message ?? {};
|
|
1338
|
+
const content = inner.content;
|
|
1279
1339
|
const toolUseResult = message.tool_use_result;
|
|
1280
1340
|
if (toolUseResult !== void 0) {
|
|
1281
1341
|
this.pendingMessages.push({
|
|
@@ -1292,6 +1352,10 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1292
1352
|
}
|
|
1293
1353
|
handleResultMessage(message) {
|
|
1294
1354
|
this.flushLlmTurn();
|
|
1355
|
+
if (message.result !== void 0) {
|
|
1356
|
+
this.rootOutput = message.result;
|
|
1357
|
+
}
|
|
1358
|
+
this.completeRootSpan();
|
|
1295
1359
|
const metadata = {};
|
|
1296
1360
|
for (const attr of [
|
|
1297
1361
|
"num_turns",
|
|
@@ -1355,6 +1419,9 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1355
1419
|
this.runToSpan.clear();
|
|
1356
1420
|
this.traceId = null;
|
|
1357
1421
|
this.rootSpanId = null;
|
|
1422
|
+
this.hasRootInput = false;
|
|
1423
|
+
this.rootInput = void 0;
|
|
1424
|
+
this.rootOutput = void 0;
|
|
1358
1425
|
this.activeContext = null;
|
|
1359
1426
|
this.traceStartedAt = null;
|
|
1360
1427
|
this.conversationHistory = [];
|
|
@@ -2960,14 +3027,15 @@ var Bitfab = class {
|
|
|
2960
3027
|
* execution as Bitfab spans with proper parent-child hierarchy.
|
|
2961
3028
|
*
|
|
2962
3029
|
* ```typescript
|
|
3030
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
3031
|
+
*
|
|
2963
3032
|
* const handler = client.getClaudeAgentHandler("my-agent");
|
|
2964
3033
|
* const options = handler.instrumentOptions({
|
|
2965
3034
|
* model: "claude-sonnet-4-5-...",
|
|
2966
3035
|
* });
|
|
2967
|
-
* const
|
|
2968
|
-
*
|
|
2969
|
-
*
|
|
2970
|
-
* for await (const msg of handler.wrapResponse(sdkClient.receiveResponse())) {
|
|
3036
|
+
* for await (const msg of handler.wrapQuery(
|
|
3037
|
+
* query({ prompt: "Do something", options })
|
|
3038
|
+
* )) {
|
|
2971
3039
|
* // process messages
|
|
2972
3040
|
* }
|
|
2973
3041
|
* ```
|