@bitfab/sdk 0.28.9 → 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-VQ4GMKQ7.js → chunk-ZBWTCBVQ.js} +141 -33
- package/dist/chunk-ZBWTCBVQ.js.map +1 -0
- package/dist/index.cjs +141 -32
- 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 +141 -32
- 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-VQ4GMKQ7.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -683,7 +683,7 @@ __export(index_exports, {
|
|
|
683
683
|
module.exports = __toCommonJS(index_exports);
|
|
684
684
|
|
|
685
685
|
// src/version.generated.ts
|
|
686
|
-
var __version__ = "0.28.
|
|
686
|
+
var __version__ = "0.28.11";
|
|
687
687
|
|
|
688
688
|
// src/constants.ts
|
|
689
689
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
@@ -923,6 +923,50 @@ var HttpClient = class {
|
|
|
923
923
|
async lookupFunction(name) {
|
|
924
924
|
return this.request("/api/sdk/functions/lookup", { name });
|
|
925
925
|
}
|
|
926
|
+
async getTraceSpan(traceId, lookup) {
|
|
927
|
+
const searchParams = new URLSearchParams();
|
|
928
|
+
if (lookup.id !== void 0) {
|
|
929
|
+
searchParams.set("id", lookup.id);
|
|
930
|
+
} else {
|
|
931
|
+
searchParams.set("name", lookup.name);
|
|
932
|
+
searchParams.set("occurrence", String(lookup.occurrence ?? "last"));
|
|
933
|
+
}
|
|
934
|
+
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}/span?${searchParams.toString()}`;
|
|
935
|
+
const response = await this.get(endpoint);
|
|
936
|
+
return response.span;
|
|
937
|
+
}
|
|
938
|
+
async get(endpoint) {
|
|
939
|
+
const url = `${this.serviceUrl}${endpoint}`;
|
|
940
|
+
const controller = new AbortController();
|
|
941
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
942
|
+
try {
|
|
943
|
+
const response = await fetch(url, {
|
|
944
|
+
method: "GET",
|
|
945
|
+
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
946
|
+
signal: controller.signal
|
|
947
|
+
});
|
|
948
|
+
if (!response.ok) {
|
|
949
|
+
const errorText = await response.text();
|
|
950
|
+
throw new BitfabError(
|
|
951
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
return await response.json();
|
|
955
|
+
} catch (error) {
|
|
956
|
+
if (error instanceof BitfabError) {
|
|
957
|
+
throw error;
|
|
958
|
+
}
|
|
959
|
+
if (error instanceof Error) {
|
|
960
|
+
if (error.name === "AbortError") {
|
|
961
|
+
throw new BitfabError(`Request timed out after ${this.timeout}ms`);
|
|
962
|
+
}
|
|
963
|
+
throw new BitfabError(error.message);
|
|
964
|
+
}
|
|
965
|
+
throw new BitfabError("Unknown error occurred");
|
|
966
|
+
} finally {
|
|
967
|
+
clearTimeout(timeoutId);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
926
970
|
/**
|
|
927
971
|
* Send an internal trace (from BAML execution).
|
|
928
972
|
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
@@ -979,12 +1023,12 @@ var HttpClient = class {
|
|
|
979
1023
|
});
|
|
980
1024
|
}
|
|
981
1025
|
/**
|
|
982
|
-
* Partial update of an existing
|
|
1026
|
+
* Partial update of an existing trace identified by its Bitfab trace ID.
|
|
983
1027
|
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
984
1028
|
* returns a tracked promise that callers may optionally await.
|
|
985
1029
|
*/
|
|
986
|
-
patchTrace(
|
|
987
|
-
const endpoint = `/api/sdk/
|
|
1030
|
+
patchTrace(traceId, payload) {
|
|
1031
|
+
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}`;
|
|
988
1032
|
return awaitOnExit(
|
|
989
1033
|
this.request(endpoint, payload, { method: "PATCH" })
|
|
990
1034
|
).catch((error) => {
|
|
@@ -1322,6 +1366,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1322
1366
|
const traceId = this.ensureTrace();
|
|
1323
1367
|
const { safe: safeInput, dropped: inputDropped } = toJsonSafeReport(inputData);
|
|
1324
1368
|
const spanInfo = {
|
|
1369
|
+
id: randomUuid(),
|
|
1325
1370
|
spanId,
|
|
1326
1371
|
traceId,
|
|
1327
1372
|
parentId: parentId ?? null,
|
|
@@ -1385,6 +1430,8 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1385
1430
|
rawSpan.parent_id = spanInfo.parentId;
|
|
1386
1431
|
}
|
|
1387
1432
|
const payload = {
|
|
1433
|
+
id: spanInfo.id,
|
|
1434
|
+
traceId: spanInfo.traceId,
|
|
1388
1435
|
type: "sdk-function",
|
|
1389
1436
|
source: "typescript-sdk-claude-agent-sdk",
|
|
1390
1437
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -1414,6 +1461,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1414
1461
|
externalTrace.metadata = metadata;
|
|
1415
1462
|
}
|
|
1416
1463
|
const traceData = {
|
|
1464
|
+
id: traceId,
|
|
1417
1465
|
type: "sdk-function",
|
|
1418
1466
|
source: "typescript-sdk-claude-agent-sdk",
|
|
1419
1467
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -1682,6 +1730,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
1682
1730
|
}
|
|
1683
1731
|
Object.assign(llmContext, this.currentLlmUsage);
|
|
1684
1732
|
const spanInfo = {
|
|
1733
|
+
id: randomUuid(),
|
|
1685
1734
|
spanId,
|
|
1686
1735
|
traceId,
|
|
1687
1736
|
parentId,
|
|
@@ -2328,6 +2377,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2328
2377
|
const contexts = Object.keys(lgMetadata).length > 0 ? [lgMetadata] : [];
|
|
2329
2378
|
const { safe: safeInput, dropped: inputDropped } = toJsonSafeReport(inputData);
|
|
2330
2379
|
const spanInfo = {
|
|
2380
|
+
id: randomUuid(),
|
|
2331
2381
|
spanId: runId,
|
|
2332
2382
|
traceId: invocation.traceId,
|
|
2333
2383
|
rootRunId: invocation.rootRunId,
|
|
@@ -2406,6 +2456,8 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2406
2456
|
rawSpan.parent_id = spanInfo.parentId;
|
|
2407
2457
|
}
|
|
2408
2458
|
const payload = {
|
|
2459
|
+
id: spanInfo.id,
|
|
2460
|
+
traceId: spanInfo.traceId,
|
|
2409
2461
|
type: "sdk-function",
|
|
2410
2462
|
source: "typescript-sdk-langgraph",
|
|
2411
2463
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2421,6 +2473,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2421
2473
|
sendTraceCompletion(rootSpan, activeContext) {
|
|
2422
2474
|
const completed = activeContext === null;
|
|
2423
2475
|
const traceData = {
|
|
2476
|
+
id: rootSpan.traceId,
|
|
2424
2477
|
type: "sdk-function",
|
|
2425
2478
|
source: "typescript-sdk-langgraph",
|
|
2426
2479
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2440,6 +2493,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
2440
2493
|
}
|
|
2441
2494
|
sendTraceStart(rootSpan) {
|
|
2442
2495
|
const traceData = {
|
|
2496
|
+
id: rootSpan.traceId,
|
|
2443
2497
|
type: "sdk-function",
|
|
2444
2498
|
source: "typescript-sdk-langgraph",
|
|
2445
2499
|
traceFunctionKey: this.traceFunctionKey,
|
|
@@ -2798,6 +2852,7 @@ var ReplayEnvironment = class {
|
|
|
2798
2852
|
init_serialize();
|
|
2799
2853
|
|
|
2800
2854
|
// src/tracing.ts
|
|
2855
|
+
init_randomUuid();
|
|
2801
2856
|
var BitfabOpenAITracingProcessor = class {
|
|
2802
2857
|
/**
|
|
2803
2858
|
* Initialize the tracing processor.
|
|
@@ -2807,6 +2862,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2807
2862
|
constructor(config) {
|
|
2808
2863
|
this.activeTraces = {};
|
|
2809
2864
|
this.activeSpanMappings = {};
|
|
2865
|
+
this.canonicalTraceIds = {};
|
|
2810
2866
|
this.httpClient = new HttpClient({
|
|
2811
2867
|
apiKey: config.apiKey,
|
|
2812
2868
|
serviceUrl: config.serviceUrl ?? DEFAULT_SERVICE_URL,
|
|
@@ -2814,6 +2870,15 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2814
2870
|
});
|
|
2815
2871
|
this.getActiveSpanContext = config.getActiveSpanContext ?? null;
|
|
2816
2872
|
}
|
|
2873
|
+
getCanonicalTraceId(sourceTraceId) {
|
|
2874
|
+
const existing = this.canonicalTraceIds[sourceTraceId];
|
|
2875
|
+
if (existing) {
|
|
2876
|
+
return existing;
|
|
2877
|
+
}
|
|
2878
|
+
const created = randomUuid();
|
|
2879
|
+
this.canonicalTraceIds[sourceTraceId] = created;
|
|
2880
|
+
return created;
|
|
2881
|
+
}
|
|
2817
2882
|
/**
|
|
2818
2883
|
* Called when a trace is started.
|
|
2819
2884
|
* If there's an active withSpan context, the trace ID is remapped to the
|
|
@@ -2825,7 +2890,12 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2825
2890
|
if (activeContext) {
|
|
2826
2891
|
this.activeSpanMappings[trace.traceId] = activeContext;
|
|
2827
2892
|
}
|
|
2828
|
-
|
|
2893
|
+
const canonicalTraceId = activeContext?.traceId ?? this.getCanonicalTraceId(trace.traceId);
|
|
2894
|
+
this.canonicalTraceIds[trace.traceId] = canonicalTraceId;
|
|
2895
|
+
this.sendTrace(trace, {
|
|
2896
|
+
id: canonicalTraceId,
|
|
2897
|
+
sourceTraceId: activeContext?.traceId
|
|
2898
|
+
});
|
|
2829
2899
|
}
|
|
2830
2900
|
/**
|
|
2831
2901
|
* Called when a trace is ended.
|
|
@@ -2834,11 +2904,13 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2834
2904
|
*/
|
|
2835
2905
|
async onTraceEnd(trace) {
|
|
2836
2906
|
const mapping = this.activeSpanMappings[trace.traceId];
|
|
2837
|
-
this.sendTrace(
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2907
|
+
this.sendTrace(trace, {
|
|
2908
|
+
completed: mapping === void 0,
|
|
2909
|
+
id: mapping?.traceId ?? this.getCanonicalTraceId(trace.traceId),
|
|
2910
|
+
sourceTraceId: mapping?.traceId
|
|
2911
|
+
});
|
|
2841
2912
|
delete this.activeSpanMappings[trace.traceId];
|
|
2913
|
+
delete this.canonicalTraceIds[trace.traceId];
|
|
2842
2914
|
delete this.activeTraces[trace.traceId];
|
|
2843
2915
|
}
|
|
2844
2916
|
/**
|
|
@@ -2868,22 +2940,25 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2868
2940
|
async shutdown(_timeout) {
|
|
2869
2941
|
this.activeTraces = {};
|
|
2870
2942
|
this.activeSpanMappings = {};
|
|
2943
|
+
this.canonicalTraceIds = {};
|
|
2871
2944
|
}
|
|
2872
2945
|
/**
|
|
2873
2946
|
* Send trace to Bitfab API (fire-and-forget).
|
|
2874
2947
|
* When traceIdOverride is provided, the trace ID is remapped to link
|
|
2875
2948
|
* the OpenAI trace into an outer withSpan trace.
|
|
2876
2949
|
*/
|
|
2877
|
-
sendTrace(trace,
|
|
2950
|
+
sendTrace(trace, options = {}) {
|
|
2878
2951
|
try {
|
|
2879
|
-
const { completed, ...traceOverrides } = overrides;
|
|
2880
2952
|
const traceData = trace.toJSON();
|
|
2881
|
-
|
|
2953
|
+
if (options.sourceTraceId) {
|
|
2954
|
+
traceData.id = options.sourceTraceId;
|
|
2955
|
+
}
|
|
2882
2956
|
this.httpClient.sendExternalTrace({
|
|
2957
|
+
...options.id && { id: options.id },
|
|
2883
2958
|
type: "openai",
|
|
2884
2959
|
source: "typescript-sdk-openai-tracing",
|
|
2885
2960
|
externalTrace: traceData,
|
|
2886
|
-
completed: completed ?? false
|
|
2961
|
+
completed: options.completed ?? false
|
|
2887
2962
|
});
|
|
2888
2963
|
} catch {
|
|
2889
2964
|
}
|
|
@@ -2969,6 +3044,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2969
3044
|
*/
|
|
2970
3045
|
buildSpanPayload(serializedSpan, errors) {
|
|
2971
3046
|
const payload = {
|
|
3047
|
+
id: randomUuid(),
|
|
2972
3048
|
type: "openai",
|
|
2973
3049
|
source: "typescript-sdk-openai-tracing",
|
|
2974
3050
|
sourceTraceId: serializedSpan.trace_id ?? "unknown",
|
|
@@ -2991,6 +3067,10 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
2991
3067
|
this.extractSpanInputResponse(span, serializedSpan, errors);
|
|
2992
3068
|
this.applySpanOverrides(serializedSpan, span.traceId ?? "");
|
|
2993
3069
|
const payload = this.buildSpanPayload(serializedSpan, errors);
|
|
3070
|
+
const canonicalTraceId = span.traceId ? this.getCanonicalTraceId(span.traceId) : void 0;
|
|
3071
|
+
if (canonicalTraceId) {
|
|
3072
|
+
payload.traceId = canonicalTraceId;
|
|
3073
|
+
}
|
|
2994
3074
|
this.httpClient.sendExternalSpan(payload);
|
|
2995
3075
|
}
|
|
2996
3076
|
};
|
|
@@ -3129,8 +3209,11 @@ init_warnOnce();
|
|
|
3129
3209
|
var activeTraceStates = /* @__PURE__ */ new Map();
|
|
3130
3210
|
var pendingSpanPromises = /* @__PURE__ */ new Map();
|
|
3131
3211
|
var asyncLocalStorage = null;
|
|
3212
|
+
var initializeAsyncContext = () => {
|
|
3213
|
+
asyncLocalStorage ?? (asyncLocalStorage = createAsyncLocalStorage());
|
|
3214
|
+
};
|
|
3132
3215
|
var asyncLocalStorageReady = asyncStorageReady.then(() => {
|
|
3133
|
-
|
|
3216
|
+
initializeAsyncContext();
|
|
3134
3217
|
});
|
|
3135
3218
|
var browserSpanStack = [];
|
|
3136
3219
|
function getSpanStack() {
|
|
@@ -3304,24 +3387,19 @@ function extractContextFromCollector(collector) {
|
|
|
3304
3387
|
return null;
|
|
3305
3388
|
}
|
|
3306
3389
|
}
|
|
3307
|
-
var
|
|
3308
|
-
var TRACE_ID_MAX_LENGTH = 256;
|
|
3390
|
+
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;
|
|
3309
3391
|
function validateTraceId(traceId) {
|
|
3310
|
-
if (typeof traceId !== "string" || traceId
|
|
3311
|
-
throw new BitfabError("traceId
|
|
3392
|
+
if (typeof traceId !== "string" || !UUID_PATTERN.test(traceId)) {
|
|
3393
|
+
throw new BitfabError("traceId must be a valid Bitfab trace ID");
|
|
3312
3394
|
}
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
);
|
|
3317
|
-
}
|
|
3318
|
-
if (!TRACE_ID_PATTERN.test(traceId)) {
|
|
3319
|
-
throw new BitfabError(
|
|
3320
|
-
`traceId may only contain letters, digits, "_", "-", ".", ":"`
|
|
3321
|
-
);
|
|
3395
|
+
}
|
|
3396
|
+
function validateSpanId(id) {
|
|
3397
|
+
if (typeof id !== "string" || !UUID_PATTERN.test(id)) {
|
|
3398
|
+
throw new BitfabError("id must be a valid Bitfab span ID");
|
|
3322
3399
|
}
|
|
3323
3400
|
}
|
|
3324
3401
|
var noOpSpan = {
|
|
3402
|
+
id: "",
|
|
3325
3403
|
traceId: "",
|
|
3326
3404
|
addContext() {
|
|
3327
3405
|
},
|
|
@@ -3345,6 +3423,7 @@ function getCurrentSpan() {
|
|
|
3345
3423
|
return noOpSpan;
|
|
3346
3424
|
}
|
|
3347
3425
|
return {
|
|
3426
|
+
id: current.spanId,
|
|
3348
3427
|
traceId: current.traceId,
|
|
3349
3428
|
addContext(context) {
|
|
3350
3429
|
try {
|
|
@@ -3899,6 +3978,7 @@ var Bitfab = class {
|
|
|
3899
3978
|
if (!self.isTracingEnabled()) {
|
|
3900
3979
|
return fn.apply(this, args);
|
|
3901
3980
|
}
|
|
3981
|
+
initializeAsyncContext();
|
|
3902
3982
|
if (!asyncLocalStorage && !isAsyncStorageInitDone()) {
|
|
3903
3983
|
return asyncLocalStorageReady.then(
|
|
3904
3984
|
() => wrappedFn.apply(this, args)
|
|
@@ -4140,20 +4220,19 @@ var Bitfab = class {
|
|
|
4140
4220
|
}
|
|
4141
4221
|
/**
|
|
4142
4222
|
* Get a detached handle to a previously-created trace, looked up by the
|
|
4143
|
-
*
|
|
4223
|
+
* canonical Bitfab trace ID.
|
|
4144
4224
|
*
|
|
4145
4225
|
* The returned handle is not tied to AsyncLocalStorage - each method sends
|
|
4146
4226
|
* to the server immediately. Useful for adding context to a trace from a
|
|
4147
4227
|
* different process or thread than the one that created it.
|
|
4148
4228
|
*
|
|
4149
|
-
* Throws synchronously if `traceId` is
|
|
4150
|
-
*
|
|
4151
|
-
* no trace exists with that id in the org; the failure surfaces as a
|
|
4229
|
+
* Throws synchronously if `traceId` is not a valid Bitfab trace ID. The
|
|
4230
|
+
* server returns 404 if no trace exists with that ID in the org; the failure surfaces as a
|
|
4152
4231
|
* logged warning (fire-and-forget) or via the awaited promise.
|
|
4153
4232
|
*
|
|
4154
4233
|
* Example:
|
|
4155
4234
|
* ```typescript
|
|
4156
|
-
* const trace = client.getTrace(
|
|
4235
|
+
* const trace = client.getTrace(traceId);
|
|
4157
4236
|
* await trace.addContext({ refund_status: "approved" });
|
|
4158
4237
|
* await trace.setMetadata({ region: "us-west" });
|
|
4159
4238
|
* ```
|
|
@@ -4193,6 +4272,33 @@ var Bitfab = class {
|
|
|
4193
4272
|
}
|
|
4194
4273
|
};
|
|
4195
4274
|
}
|
|
4275
|
+
/**
|
|
4276
|
+
* Fetch one persisted span from a trace without loading the full trace.
|
|
4277
|
+
* Name lookups return the last matching span by default. Pass `occurrence`
|
|
4278
|
+
* as `"first"` or a zero-based index to select a different match.
|
|
4279
|
+
*/
|
|
4280
|
+
async getTraceSpan(traceId, lookup) {
|
|
4281
|
+
validateTraceId(traceId);
|
|
4282
|
+
const hasId = lookup.id !== void 0;
|
|
4283
|
+
const hasName = lookup.name !== void 0;
|
|
4284
|
+
if (hasId === hasName) {
|
|
4285
|
+
throw new BitfabError("Provide exactly one of id or name");
|
|
4286
|
+
}
|
|
4287
|
+
if (hasId) {
|
|
4288
|
+
validateSpanId(lookup.id);
|
|
4289
|
+
} else {
|
|
4290
|
+
if (lookup.name.length === 0) {
|
|
4291
|
+
throw new BitfabError("name must be a non-empty string");
|
|
4292
|
+
}
|
|
4293
|
+
const occurrence = lookup.occurrence ?? "last";
|
|
4294
|
+
if (occurrence !== "first" && occurrence !== "last" && (!Number.isInteger(occurrence) || occurrence < 0)) {
|
|
4295
|
+
throw new BitfabError(
|
|
4296
|
+
'occurrence must be "first", "last", or a non-negative integer'
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
return this.httpClient.getTraceSpan(traceId, lookup);
|
|
4301
|
+
}
|
|
4196
4302
|
/**
|
|
4197
4303
|
* Get a function wrapper for a specific trace function key.
|
|
4198
4304
|
*
|
|
@@ -4251,6 +4357,7 @@ var Bitfab = class {
|
|
|
4251
4357
|
};
|
|
4252
4358
|
}
|
|
4253
4359
|
return this.httpClient.sendExternalTrace({
|
|
4360
|
+
id: params.traceId,
|
|
4254
4361
|
type: "sdk-function",
|
|
4255
4362
|
source: "typescript-sdk-function",
|
|
4256
4363
|
traceFunctionKey: params.traceFunctionKey,
|
|
@@ -4306,6 +4413,8 @@ var Bitfab = class {
|
|
|
4306
4413
|
externalSpan.input_source_span_id = params.inputSourceSpanId;
|
|
4307
4414
|
}
|
|
4308
4415
|
return this.httpClient.sendExternalSpan({
|
|
4416
|
+
id: params.spanId,
|
|
4417
|
+
traceId: params.traceId,
|
|
4309
4418
|
type: "sdk-function",
|
|
4310
4419
|
source: "typescript-sdk-function",
|
|
4311
4420
|
sourceTraceId: params.traceId,
|