bitfab 0.28.10 → 0.28.11
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-SK4TNXRC.js → chunk-ZBWTCBVQ.js} +136 -32
- package/dist/chunk-ZBWTCBVQ.js.map +1 -0
- package/dist/index.cjs +136 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -9
- package/dist/index.d.ts +44 -9
- package/dist/index.js +1 -1
- package/dist/node.cjs +136 -31
- 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 +1 -1
- package/package.json +1 -1
- package/dist/chunk-SK4TNXRC.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -692,7 +692,7 @@ __export(index_exports, {
|
|
|
692
692
|
module.exports = __toCommonJS(index_exports);
|
|
693
693
|
|
|
694
694
|
// src/version.generated.ts
|
|
695
|
-
var __version__ = "0.28.
|
|
695
|
+
var __version__ = "0.28.11";
|
|
696
696
|
|
|
697
697
|
// src/constants.ts
|
|
698
698
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -932,6 +932,50 @@ var HttpClient = class {
|
|
|
932
932
|
async lookupFunction(name) {
|
|
933
933
|
return this.request("/api/sdk/functions/lookup", { name });
|
|
934
934
|
}
|
|
935
|
+
async getTraceSpan(traceId, lookup) {
|
|
936
|
+
const searchParams = new URLSearchParams();
|
|
937
|
+
if (lookup.id !== void 0) {
|
|
938
|
+
searchParams.set("id", lookup.id);
|
|
939
|
+
} else {
|
|
940
|
+
searchParams.set("name", lookup.name);
|
|
941
|
+
searchParams.set("occurrence", String(lookup.occurrence ?? "last"));
|
|
942
|
+
}
|
|
943
|
+
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}/span?${searchParams.toString()}`;
|
|
944
|
+
const response = await this.get(endpoint);
|
|
945
|
+
return response.span;
|
|
946
|
+
}
|
|
947
|
+
async get(endpoint) {
|
|
948
|
+
const url = `${this.serviceUrl}${endpoint}`;
|
|
949
|
+
const controller = new AbortController();
|
|
950
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
951
|
+
try {
|
|
952
|
+
const response = await fetch(url, {
|
|
953
|
+
method: "GET",
|
|
954
|
+
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
955
|
+
signal: controller.signal
|
|
956
|
+
});
|
|
957
|
+
if (!response.ok) {
|
|
958
|
+
const errorText = await response.text();
|
|
959
|
+
throw new BitfabError(
|
|
960
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
return await response.json();
|
|
964
|
+
} catch (error) {
|
|
965
|
+
if (error instanceof BitfabError) {
|
|
966
|
+
throw error;
|
|
967
|
+
}
|
|
968
|
+
if (error instanceof Error) {
|
|
969
|
+
if (error.name === "AbortError") {
|
|
970
|
+
throw new BitfabError(`Request timed out after ${this.timeout}ms`);
|
|
971
|
+
}
|
|
972
|
+
throw new BitfabError(error.message);
|
|
973
|
+
}
|
|
974
|
+
throw new BitfabError("Unknown error occurred");
|
|
975
|
+
} finally {
|
|
976
|
+
clearTimeout(timeoutId);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
935
979
|
/**
|
|
936
980
|
* Send an internal trace (from BAML execution).
|
|
937
981
|
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
@@ -988,12 +1032,12 @@ var HttpClient = class {
|
|
|
988
1032
|
});
|
|
989
1033
|
}
|
|
990
1034
|
/**
|
|
991
|
-
* Partial update of an existing
|
|
1035
|
+
* Partial update of an existing trace identified by its Bitfab trace ID.
|
|
992
1036
|
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
993
1037
|
* returns a tracked promise that callers may optionally await.
|
|
994
1038
|
*/
|
|
995
|
-
patchTrace(
|
|
996
|
-
const endpoint = `/api/sdk/
|
|
1039
|
+
patchTrace(traceId, payload) {
|
|
1040
|
+
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}`;
|
|
997
1041
|
return awaitOnExit(
|
|
998
1042
|
this.request(endpoint, payload, { method: "PATCH" })
|
|
999
1043
|
).catch((error) => {
|
|
@@ -1331,6 +1375,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1331
1375
|
const traceId = this.ensureTrace();
|
|
1332
1376
|
const { safe: safeInput, dropped: inputDropped } = toJsonSafeReport(inputData);
|
|
1333
1377
|
const spanInfo = {
|
|
1378
|
+
id: randomUuid(),
|
|
1334
1379
|
spanId,
|
|
1335
1380
|
traceId,
|
|
1336
1381
|
parentId: parentId ?? null,
|
|
@@ -1394,6 +1439,8 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1394
1439
|
rawSpan.parent_id = spanInfo.parentId;
|
|
1395
1440
|
}
|
|
1396
1441
|
const payload = {
|
|
1442
|
+
id: spanInfo.id,
|
|
1443
|
+
traceId: spanInfo.traceId,
|
|
1397
1444
|
type: "sdk-function",
|
|
1398
1445
|
source: "typescript-sdk-claude-agent-sdk",
|
|
1399
1446
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -1423,6 +1470,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1423
1470
|
externalTrace.metadata = metadata;
|
|
1424
1471
|
}
|
|
1425
1472
|
const traceData = {
|
|
1473
|
+
id: traceId,
|
|
1426
1474
|
type: "sdk-function",
|
|
1427
1475
|
source: "typescript-sdk-claude-agent-sdk",
|
|
1428
1476
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -1691,6 +1739,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1691
1739
|
}
|
|
1692
1740
|
Object.assign(llmContext, this.currentLlmUsage);
|
|
1693
1741
|
const spanInfo = {
|
|
1742
|
+
id: randomUuid(),
|
|
1694
1743
|
spanId,
|
|
1695
1744
|
traceId,
|
|
1696
1745
|
parentId,
|
|
@@ -2337,6 +2386,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2337
2386
|
const contexts = Object.keys(lgMetadata).length > 0 ? [lgMetadata] : [];
|
|
2338
2387
|
const { safe: safeInput, dropped: inputDropped } = toJsonSafeReport(inputData);
|
|
2339
2388
|
const spanInfo = {
|
|
2389
|
+
id: randomUuid(),
|
|
2340
2390
|
spanId: runId,
|
|
2341
2391
|
traceId: invocation.traceId,
|
|
2342
2392
|
rootRunId: invocation.rootRunId,
|
|
@@ -2415,6 +2465,8 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2415
2465
|
rawSpan.parent_id = spanInfo.parentId;
|
|
2416
2466
|
}
|
|
2417
2467
|
const payload = {
|
|
2468
|
+
id: spanInfo.id,
|
|
2469
|
+
traceId: spanInfo.traceId,
|
|
2418
2470
|
type: "sdk-function",
|
|
2419
2471
|
source: "typescript-sdk-langgraph",
|
|
2420
2472
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2430,6 +2482,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2430
2482
|
sendTraceCompletion(rootSpan, activeContext) {
|
|
2431
2483
|
const completed = activeContext === null;
|
|
2432
2484
|
const traceData = {
|
|
2485
|
+
id: rootSpan.traceId,
|
|
2433
2486
|
type: "sdk-function",
|
|
2434
2487
|
source: "typescript-sdk-langgraph",
|
|
2435
2488
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2449,6 +2502,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2449
2502
|
}
|
|
2450
2503
|
sendTraceStart(rootSpan) {
|
|
2451
2504
|
const traceData = {
|
|
2505
|
+
id: rootSpan.traceId,
|
|
2452
2506
|
type: "sdk-function",
|
|
2453
2507
|
source: "typescript-sdk-langgraph",
|
|
2454
2508
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2807,6 +2861,7 @@ var ReplayEnvironment = class {
|
|
|
2807
2861
|
init_serialize();
|
|
2808
2862
|
|
|
2809
2863
|
// src/tracing.ts
|
|
2864
|
+
init_randomUuid();
|
|
2810
2865
|
var BitfabOpenAITracingProcessor = class {
|
|
2811
2866
|
/**
|
|
2812
2867
|
* Initialize the tracing processor.
|
|
@@ -2816,6 +2871,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2816
2871
|
constructor(config) {
|
|
2817
2872
|
this.activeTraces = {};
|
|
2818
2873
|
this.activeSpanMappings = {};
|
|
2874
|
+
this.canonicalTraceIds = {};
|
|
2819
2875
|
this.httpClient = new HttpClient({
|
|
2820
2876
|
apiKey: config.apiKey,
|
|
2821
2877
|
serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,
|
|
@@ -2823,6 +2879,15 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2823
2879
|
});
|
|
2824
2880
|
this.getActiveSpanContext = config.getActiveSpanContext ?? null;
|
|
2825
2881
|
}
|
|
2882
|
+
getCanonicalTraceId(sourceTraceId) {
|
|
2883
|
+
const existing = this.canonicalTraceIds[sourceTraceId];
|
|
2884
|
+
if (existing) {
|
|
2885
|
+
return existing;
|
|
2886
|
+
}
|
|
2887
|
+
const created = randomUuid();
|
|
2888
|
+
this.canonicalTraceIds[sourceTraceId] = created;
|
|
2889
|
+
return created;
|
|
2890
|
+
}
|
|
2826
2891
|
/**
|
|
2827
2892
|
* Called when a trace is started.
|
|
2828
2893
|
* If there's an active withSpan context, the trace ID is remapped to the
|
|
@@ -2834,7 +2899,12 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2834
2899
|
if (activeContext) {
|
|
2835
2900
|
this.activeSpanMappings[trace.traceId] = activeContext;
|
|
2836
2901
|
}
|
|
2837
|
-
|
|
2902
|
+
const canonicalTraceId = activeContext?.traceId ?? this.getCanonicalTraceId(trace.traceId);
|
|
2903
|
+
this.canonicalTraceIds[trace.traceId] = canonicalTraceId;
|
|
2904
|
+
this.sendTrace(trace, {
|
|
2905
|
+
id: canonicalTraceId,
|
|
2906
|
+
sourceTraceId: activeContext?.traceId
|
|
2907
|
+
});
|
|
2838
2908
|
}
|
|
2839
2909
|
/**
|
|
2840
2910
|
* Called when a trace is ended.
|
|
@@ -2843,11 +2913,13 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2843
2913
|
*/
|
|
2844
2914
|
async onTraceEnd(trace) {
|
|
2845
2915
|
const mapping = this.activeSpanMappings[trace.traceId];
|
|
2846
|
-
this.sendTrace(
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2916
|
+
this.sendTrace(trace, {
|
|
2917
|
+
completed: mapping === void 0,
|
|
2918
|
+
id: mapping?.traceId ?? this.getCanonicalTraceId(trace.traceId),
|
|
2919
|
+
sourceTraceId: mapping?.traceId
|
|
2920
|
+
});
|
|
2850
2921
|
delete this.activeSpanMappings[trace.traceId];
|
|
2922
|
+
delete this.canonicalTraceIds[trace.traceId];
|
|
2851
2923
|
delete this.activeTraces[trace.traceId];
|
|
2852
2924
|
}
|
|
2853
2925
|
/**
|
|
@@ -2877,22 +2949,25 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2877
2949
|
async shutdown(_timeout) {
|
|
2878
2950
|
this.activeTraces = {};
|
|
2879
2951
|
this.activeSpanMappings = {};
|
|
2952
|
+
this.canonicalTraceIds = {};
|
|
2880
2953
|
}
|
|
2881
2954
|
/**
|
|
2882
2955
|
* Send trace to Bitfab API (fire-and-forget).
|
|
2883
2956
|
* When traceIdOverride is provided, the trace ID is remapped to link
|
|
2884
2957
|
* the OpenAI trace into an outer withSpan trace.
|
|
2885
2958
|
*/
|
|
2886
|
-
sendTrace(trace,
|
|
2959
|
+
sendTrace(trace, options = {}) {
|
|
2887
2960
|
try {
|
|
2888
|
-
const { completed, ...traceOverrides } = overrides;
|
|
2889
2961
|
const traceData = trace.toJSON();
|
|
2890
|
-
|
|
2962
|
+
if (options.sourceTraceId) {
|
|
2963
|
+
traceData.id = options.sourceTraceId;
|
|
2964
|
+
}
|
|
2891
2965
|
this.httpClient.sendExternalTrace({
|
|
2966
|
+
...options.id && { id: options.id },
|
|
2892
2967
|
type: "openai",
|
|
2893
2968
|
source: "typescript-sdk-openai-tracing",
|
|
2894
2969
|
externalTrace: traceData,
|
|
2895
|
-
completed: completed ?? false
|
|
2970
|
+
completed: options.completed ?? false
|
|
2896
2971
|
});
|
|
2897
2972
|
} catch {
|
|
2898
2973
|
}
|
|
@@ -2978,6 +3053,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2978
3053
|
*/
|
|
2979
3054
|
buildSpanPayload(serializedSpan, errors) {
|
|
2980
3055
|
const payload = {
|
|
3056
|
+
id: randomUuid(),
|
|
2981
3057
|
type: "openai",
|
|
2982
3058
|
source: "typescript-sdk-openai-tracing",
|
|
2983
3059
|
sourceTraceId: serializedSpan.trace_id ?? "unknown",
|
|
@@ -3000,6 +3076,10 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
3000
3076
|
this.extractSpanInputResponse(span, serializedSpan, errors);
|
|
3001
3077
|
this.applySpanOverrides(serializedSpan, span.traceId ?? "");
|
|
3002
3078
|
const payload = this.buildSpanPayload(serializedSpan, errors);
|
|
3079
|
+
const canonicalTraceId = span.traceId ? this.getCanonicalTraceId(span.traceId) : void 0;
|
|
3080
|
+
if (canonicalTraceId) {
|
|
3081
|
+
payload.traceId = canonicalTraceId;
|
|
3082
|
+
}
|
|
3003
3083
|
this.httpClient.sendExternalSpan(payload);
|
|
3004
3084
|
}
|
|
3005
3085
|
};
|
|
@@ -3316,24 +3396,19 @@ function extractContextFromCollector(collector) {
|
|
|
3316
3396
|
return null;
|
|
3317
3397
|
}
|
|
3318
3398
|
}
|
|
3319
|
-
var
|
|
3320
|
-
var TRACE_ID_MAX_LENGTH = 256;
|
|
3399
|
+
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
3321
3400
|
function validateTraceId(traceId) {
|
|
3322
|
-
if (typeof traceId !== "string" || traceId
|
|
3323
|
-
throw new BitfabError("traceId
|
|
3401
|
+
if (typeof traceId !== "string" || !UUID_PATTERN.test(traceId)) {
|
|
3402
|
+
throw new BitfabError("traceId must be a valid Bitfab trace ID");
|
|
3324
3403
|
}
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
);
|
|
3329
|
-
}
|
|
3330
|
-
if (!TRACE_ID_PATTERN.test(traceId)) {
|
|
3331
|
-
throw new BitfabError(
|
|
3332
|
-
`traceId may only contain letters, digits, "_", "-", ".", ":"`
|
|
3333
|
-
);
|
|
3404
|
+
}
|
|
3405
|
+
function validateSpanId(id) {
|
|
3406
|
+
if (typeof id !== "string" || !UUID_PATTERN.test(id)) {
|
|
3407
|
+
throw new BitfabError("id must be a valid Bitfab span ID");
|
|
3334
3408
|
}
|
|
3335
3409
|
}
|
|
3336
3410
|
var noOpSpan = {
|
|
3411
|
+
id: "",
|
|
3337
3412
|
traceId: "",
|
|
3338
3413
|
addContext() {
|
|
3339
3414
|
},
|
|
@@ -3357,6 +3432,7 @@ function getCurrentSpan() {
|
|
|
3357
3432
|
return noOpSpan;
|
|
3358
3433
|
}
|
|
3359
3434
|
return {
|
|
3435
|
+
id: current.spanId,
|
|
3360
3436
|
traceId: current.traceId,
|
|
3361
3437
|
addContext(context) {
|
|
3362
3438
|
try {
|
|
@@ -4153,20 +4229,19 @@ var Bitfab = class {
|
|
|
4153
4229
|
}
|
|
4154
4230
|
/**
|
|
4155
4231
|
* Get a detached handle to a previously-created trace, looked up by the
|
|
4156
|
-
*
|
|
4232
|
+
* canonical Bitfab trace ID.
|
|
4157
4233
|
*
|
|
4158
4234
|
* The returned handle is not tied to AsyncLocalStorage - each method sends
|
|
4159
4235
|
* to the server immediately. Useful for adding context to a trace from a
|
|
4160
4236
|
* different process or thread than the one that created it.
|
|
4161
4237
|
*
|
|
4162
|
-
* Throws synchronously if `traceId` is
|
|
4163
|
-
*
|
|
4164
|
-
* no trace exists with that id in the org; the failure surfaces as a
|
|
4238
|
+
* Throws synchronously if `traceId` is not a valid Bitfab trace ID. The
|
|
4239
|
+
* server returns 404 if no trace exists with that ID in the org; the failure surfaces as a
|
|
4165
4240
|
* logged warning (fire-and-forget) or via the awaited promise.
|
|
4166
4241
|
*
|
|
4167
4242
|
* Example:
|
|
4168
4243
|
* ```typescript
|
|
4169
|
-
* const trace = client.getTrace(
|
|
4244
|
+
* const trace = client.getTrace(traceId);
|
|
4170
4245
|
* await trace.addContext({ refund_status: "approved" });
|
|
4171
4246
|
* await trace.setMetadata({ region: "us-west" });
|
|
4172
4247
|
* ```
|
|
@@ -4206,6 +4281,33 @@ var Bitfab = class {
|
|
|
4206
4281
|
}
|
|
4207
4282
|
};
|
|
4208
4283
|
}
|
|
4284
|
+
/**
|
|
4285
|
+
* Fetch one persisted span from a trace without loading the full trace.
|
|
4286
|
+
* Name lookups return the last matching span by default. Pass `occurrence`
|
|
4287
|
+
* as `"first"` or a zero-based index to select a different match.
|
|
4288
|
+
*/
|
|
4289
|
+
async getTraceSpan(traceId, lookup) {
|
|
4290
|
+
validateTraceId(traceId);
|
|
4291
|
+
const hasId = lookup.id !== void 0;
|
|
4292
|
+
const hasName = lookup.name !== void 0;
|
|
4293
|
+
if (hasId === hasName) {
|
|
4294
|
+
throw new BitfabError("Provide exactly one of id or name");
|
|
4295
|
+
}
|
|
4296
|
+
if (hasId) {
|
|
4297
|
+
validateSpanId(lookup.id);
|
|
4298
|
+
} else {
|
|
4299
|
+
if (lookup.name.length === 0) {
|
|
4300
|
+
throw new BitfabError("name must be a non-empty string");
|
|
4301
|
+
}
|
|
4302
|
+
const occurrence = lookup.occurrence ?? "last";
|
|
4303
|
+
if (occurrence !== "first" && occurrence !== "last" && (!Number.isInteger(occurrence) || occurrence < 0)) {
|
|
4304
|
+
throw new BitfabError(
|
|
4305
|
+
'occurrence must be "first", "last", or a non-negative integer'
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
return this.httpClient.getTraceSpan(traceId, lookup);
|
|
4310
|
+
}
|
|
4209
4311
|
/**
|
|
4210
4312
|
* Get a function wrapper for a specific trace function key.
|
|
4211
4313
|
*
|
|
@@ -4264,6 +4366,7 @@ var Bitfab = class {
|
|
|
4264
4366
|
};
|
|
4265
4367
|
}
|
|
4266
4368
|
return this.httpClient.sendExternalTrace({
|
|
4369
|
+
id: params.traceId,
|
|
4267
4370
|
type: "sdk-function",
|
|
4268
4371
|
source: "typescript-sdk-function",
|
|
4269
4372
|
traceFunctionKey: params.traceFunctionKey,
|
|
@@ -4319,6 +4422,8 @@ var Bitfab = class {
|
|
|
4319
4422
|
externalSpan.input_source_span_id = params.inputSourceSpanId;
|
|
4320
4423
|
}
|
|
4321
4424
|
return this.httpClient.sendExternalSpan({
|
|
4425
|
+
id: params.spanId,
|
|
4426
|
+
traceId: params.traceId,
|
|
4322
4427
|
type: "sdk-function",
|
|
4323
4428
|
source: "typescript-sdk-function",
|
|
4324
4429
|
sourceTraceId: params.traceId,
|