raindrop-ai 0.4.0 → 0.5.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/README.md +168 -0
- package/dist/{chunk-MZZJWWWB.mjs → chunk-AUNFORWV.mjs} +1213 -860
- package/dist/chunk-HFHHGRTW.mjs +1201 -0
- package/dist/index-CQj4bn2v.d.mts +60760 -0
- package/dist/index-CQj4bn2v.d.ts +60760 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11422 -6431
- package/dist/index.mjs +3397 -176
- package/dist/portable-runtime-GBE3SHBZ.mjs +193 -0
- package/dist/tracing/index.d.mts +2 -1
- package/dist/tracing/index.d.ts +2 -1
- package/dist/tracing/index.js +1301 -982
- package/dist/tracing/index.mjs +1 -1
- package/package.json +19 -12
- package/dist/index-CDmWtd83.d.mts +0 -1525
- package/dist/index-CDmWtd83.d.ts +0 -1525
|
@@ -4,7 +4,82 @@ if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
|
4
4
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
// ../core/dist/chunk-
|
|
7
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
8
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
9
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
10
|
+
var EvalScopeStorage = class {
|
|
11
|
+
constructor() {
|
|
12
|
+
this._als = null;
|
|
13
|
+
this._probed = false;
|
|
14
|
+
}
|
|
15
|
+
maybeAdoptAsyncLocalStorage() {
|
|
16
|
+
if (this._probed) return;
|
|
17
|
+
this._probed = true;
|
|
18
|
+
try {
|
|
19
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
20
|
+
if (!Ctor) return;
|
|
21
|
+
const als = new Ctor();
|
|
22
|
+
als.run(PROBE_SCOPE, () => {
|
|
23
|
+
});
|
|
24
|
+
this._als = als;
|
|
25
|
+
} catch (e) {
|
|
26
|
+
this._als = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
run(scope, callback) {
|
|
30
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
31
|
+
if (this._als) return this._als.run(scope, callback);
|
|
32
|
+
const previous = this._syncScope;
|
|
33
|
+
this._syncScope = scope;
|
|
34
|
+
try {
|
|
35
|
+
return callback();
|
|
36
|
+
} finally {
|
|
37
|
+
this._syncScope = previous;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
current() {
|
|
41
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
42
|
+
if (this._als) return this._als.getStore();
|
|
43
|
+
return this._syncScope;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
47
|
+
function evalScopeStorage() {
|
|
48
|
+
const holder = globalThis;
|
|
49
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
50
|
+
if (!storage) {
|
|
51
|
+
storage = new EvalScopeStorage();
|
|
52
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
53
|
+
}
|
|
54
|
+
return storage;
|
|
55
|
+
}
|
|
56
|
+
function withEvalScope(scope, callback) {
|
|
57
|
+
const correlationId = scope == null ? void 0 : scope.correlationId;
|
|
58
|
+
if (typeof correlationId !== "string" || correlationId.length === 0) {
|
|
59
|
+
return callback();
|
|
60
|
+
}
|
|
61
|
+
let storage;
|
|
62
|
+
try {
|
|
63
|
+
storage = evalScopeStorage();
|
|
64
|
+
} catch (e) {
|
|
65
|
+
}
|
|
66
|
+
if (!storage) return callback();
|
|
67
|
+
return storage.run({ correlationId }, callback);
|
|
68
|
+
}
|
|
69
|
+
function currentEvalScope() {
|
|
70
|
+
try {
|
|
71
|
+
return evalScopeStorage().current();
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function evalScopeAttributes() {
|
|
77
|
+
const scope = currentEvalScope();
|
|
78
|
+
if (!scope) return {};
|
|
79
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ../core/dist/chunk-T53LQAH7.js
|
|
8
83
|
function normalizeFeatureFlags(input) {
|
|
9
84
|
if (Array.isArray(input)) {
|
|
10
85
|
return Object.fromEntries(input.map((name) => [name, "true"]));
|
|
@@ -427,6 +502,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
427
502
|
const resp = await runWithTracingSuppressed(
|
|
428
503
|
() => fetch(url, {
|
|
429
504
|
method: "POST",
|
|
505
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
430
506
|
headers: {
|
|
431
507
|
"Content-Type": "application/json",
|
|
432
508
|
...headers
|
|
@@ -566,6 +642,66 @@ function attrDouble(key, value) {
|
|
|
566
642
|
if (!Number.isFinite(value)) return void 0;
|
|
567
643
|
return { key, value: { doubleValue: value } };
|
|
568
644
|
}
|
|
645
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
646
|
+
function state() {
|
|
647
|
+
const holder = globalThis;
|
|
648
|
+
let current = holder[STATE_KEY];
|
|
649
|
+
if (!current) {
|
|
650
|
+
let storage = null;
|
|
651
|
+
try {
|
|
652
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
653
|
+
if (Ctor) storage = new Ctor();
|
|
654
|
+
} catch (e) {
|
|
655
|
+
storage = null;
|
|
656
|
+
}
|
|
657
|
+
current = {
|
|
658
|
+
storage,
|
|
659
|
+
syncDestination: void 0,
|
|
660
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
661
|
+
};
|
|
662
|
+
holder[STATE_KEY] = current;
|
|
663
|
+
}
|
|
664
|
+
return current;
|
|
665
|
+
}
|
|
666
|
+
function withReplayTraceDestination(destination, callback) {
|
|
667
|
+
const routing = state();
|
|
668
|
+
if (routing.storage) return routing.storage.run(destination, callback);
|
|
669
|
+
const previous = routing.syncDestination;
|
|
670
|
+
routing.syncDestination = destination;
|
|
671
|
+
try {
|
|
672
|
+
return callback();
|
|
673
|
+
} finally {
|
|
674
|
+
routing.syncDestination = previous;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function currentReplayTraceDestination() {
|
|
678
|
+
var _a, _b;
|
|
679
|
+
const routing = state();
|
|
680
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
681
|
+
}
|
|
682
|
+
function rememberReplayTraceDestination(span) {
|
|
683
|
+
const destination = currentReplayTraceDestination();
|
|
684
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
685
|
+
}
|
|
686
|
+
function copyReplayTraceDestination(source, target) {
|
|
687
|
+
const destination = state().spanDestinations.get(source);
|
|
688
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
689
|
+
}
|
|
690
|
+
function replayTraceDestinationFor(value) {
|
|
691
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
692
|
+
return void 0;
|
|
693
|
+
}
|
|
694
|
+
return state().spanDestinations.get(value);
|
|
695
|
+
}
|
|
696
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
697
|
+
var _a, _b;
|
|
698
|
+
if (!destination || !spanId || !traceId) return;
|
|
699
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
700
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
701
|
+
}
|
|
702
|
+
function replayTraceUrl(baseUrl) {
|
|
703
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
704
|
+
}
|
|
569
705
|
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
570
706
|
var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
|
|
571
707
|
var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
|
|
@@ -631,31 +767,36 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
631
767
|
function localDebuggerEnabled(baseUrl) {
|
|
632
768
|
return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
|
|
633
769
|
}
|
|
770
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
634
771
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
635
772
|
var _a;
|
|
636
773
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
637
|
-
if (!baseUrl) return;
|
|
638
|
-
|
|
774
|
+
if (!baseUrl) return Promise.resolve();
|
|
775
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
639
776
|
maxAttempts: 1,
|
|
640
777
|
debug: (_a = options.debug) != null ? _a : false,
|
|
641
|
-
sdkName: options.sdkName
|
|
778
|
+
sdkName: options.sdkName,
|
|
779
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
642
780
|
}).catch(() => {
|
|
643
781
|
});
|
|
644
782
|
}
|
|
645
783
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
646
784
|
var _a;
|
|
647
785
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
648
|
-
if (!baseUrl) return;
|
|
786
|
+
if (!baseUrl) return Promise.resolve();
|
|
649
787
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
650
|
-
|
|
788
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
651
789
|
maxAttempts: 1,
|
|
652
790
|
debug: (_a = options.debug) != null ? _a : false,
|
|
653
|
-
sdkName: options.sdkName
|
|
791
|
+
sdkName: options.sdkName,
|
|
792
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
654
793
|
}).catch(() => {
|
|
655
794
|
});
|
|
656
795
|
}
|
|
657
796
|
function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
658
797
|
var _a, _b;
|
|
798
|
+
const destination = currentReplayTraceDestination();
|
|
799
|
+
if (destination && destination.kind !== "workshop") return;
|
|
659
800
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
660
801
|
if (!baseUrl) return;
|
|
661
802
|
void postJson(
|
|
@@ -1097,7 +1238,7 @@ installTracingSuppressionHook();
|
|
|
1097
1238
|
// package.json
|
|
1098
1239
|
var package_default = {
|
|
1099
1240
|
name: "raindrop-ai",
|
|
1100
|
-
version: "0.
|
|
1241
|
+
version: "0.5.0",
|
|
1101
1242
|
main: "dist/index.js",
|
|
1102
1243
|
module: "dist/index.mjs",
|
|
1103
1244
|
types: "dist/index.d.ts",
|
|
@@ -1108,9 +1249,14 @@ var package_default = {
|
|
|
1108
1249
|
},
|
|
1109
1250
|
exports: {
|
|
1110
1251
|
".": {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1252
|
+
import: {
|
|
1253
|
+
types: "./dist/index.d.mts",
|
|
1254
|
+
default: "./dist/index.mjs"
|
|
1255
|
+
},
|
|
1256
|
+
require: {
|
|
1257
|
+
types: "./dist/index.d.ts",
|
|
1258
|
+
default: "./dist/index.js"
|
|
1259
|
+
}
|
|
1114
1260
|
},
|
|
1115
1261
|
"./tracing": {
|
|
1116
1262
|
types: "./dist/tracing/index.d.ts",
|
|
@@ -1150,8 +1296,8 @@ var package_default = {
|
|
|
1150
1296
|
"@raindrop-ai/core": "workspace:*",
|
|
1151
1297
|
"@raindrop-ai/redact-pii": "workspace:*",
|
|
1152
1298
|
"@raindrop-ai/schemas": "workspace:*",
|
|
1153
|
-
ai: "^6.0.0",
|
|
1154
1299
|
"@types/node": "^20.11.17",
|
|
1300
|
+
ai: "^6.0.0",
|
|
1155
1301
|
msw: "^2.12.8",
|
|
1156
1302
|
tsup: "^8.4.0",
|
|
1157
1303
|
tsx: "^4.20.3",
|
|
@@ -1160,6 +1306,7 @@ var package_default = {
|
|
|
1160
1306
|
vitest: "^4.0.10"
|
|
1161
1307
|
},
|
|
1162
1308
|
dependencies: {
|
|
1309
|
+
"@jitl/quickjs-singlefile-cjs-release-sync": "0.32.0",
|
|
1163
1310
|
"@opentelemetry/api": "^1.9.0",
|
|
1164
1311
|
"@opentelemetry/core": "^1.30.1",
|
|
1165
1312
|
"@opentelemetry/exporter-trace-otlp-http": "^0.57.2",
|
|
@@ -1170,16 +1317,17 @@ var package_default = {
|
|
|
1170
1317
|
"@opentelemetry/sdk-trace-node": "^1.30.1",
|
|
1171
1318
|
"@traceloop/ai-semantic-conventions": "0.19.0-otel-v1",
|
|
1172
1319
|
"@traceloop/instrumentation-anthropic": "0.19.0-otel-v1",
|
|
1173
|
-
"@traceloop/instrumentation-openai": "0.19.0-otel-v1",
|
|
1174
|
-
"@traceloop/instrumentation-cohere": "0.19.0-otel-v1",
|
|
1175
1320
|
"@traceloop/instrumentation-bedrock": "0.19.0-otel-v1",
|
|
1176
|
-
"@traceloop/instrumentation-vertexai": "0.19.0-otel-v1",
|
|
1177
|
-
"@traceloop/instrumentation-pinecone": "0.19.0-otel-v1",
|
|
1178
1321
|
"@traceloop/instrumentation-chromadb": "0.19.0-otel-v1",
|
|
1179
|
-
"@traceloop/instrumentation-
|
|
1180
|
-
"@traceloop/instrumentation-together": "0.19.0-otel-v1",
|
|
1322
|
+
"@traceloop/instrumentation-cohere": "0.19.0-otel-v1",
|
|
1181
1323
|
"@traceloop/instrumentation-langchain": "0.19.0-otel-v1",
|
|
1182
1324
|
"@traceloop/instrumentation-llamaindex": "0.19.0-otel-v1",
|
|
1325
|
+
"@traceloop/instrumentation-openai": "0.19.0-otel-v1",
|
|
1326
|
+
"@traceloop/instrumentation-pinecone": "0.19.0-otel-v1",
|
|
1327
|
+
"@traceloop/instrumentation-qdrant": "0.19.0-otel-v1",
|
|
1328
|
+
"@traceloop/instrumentation-together": "0.19.0-otel-v1",
|
|
1329
|
+
"@traceloop/instrumentation-vertexai": "0.19.0-otel-v1",
|
|
1330
|
+
"quickjs-emscripten-core": "0.32.0",
|
|
1183
1331
|
weakref: "^0.2.1",
|
|
1184
1332
|
zod: "^3.23.8"
|
|
1185
1333
|
},
|
|
@@ -1233,22 +1381,136 @@ var package_default = {
|
|
|
1233
1381
|
|
|
1234
1382
|
// src/tracing/multi-project.ts
|
|
1235
1383
|
import { createHash } from "crypto";
|
|
1384
|
+
import { OTLPTraceExporter as OTLPProtoTraceExporter2 } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
1385
|
+
|
|
1386
|
+
// src/tracing/replay-routing.ts
|
|
1236
1387
|
import { OTLPTraceExporter as OTLPProtoTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
1237
|
-
var PROJECT_ID_SPAN_ATTRIBUTE = "raindrop.project_id";
|
|
1238
|
-
var AUTH_HINT_SPAN_ATTRIBUTE = "raindrop.auth_hint";
|
|
1239
1388
|
var EXPORT_SUCCESS = 0;
|
|
1240
1389
|
var EXPORT_FAILED = 1;
|
|
1390
|
+
function recordExportedSpan(destination, span) {
|
|
1391
|
+
if (typeof span !== "object" && typeof span !== "function" || span === null) return;
|
|
1392
|
+
const spanContext = span.spanContext;
|
|
1393
|
+
if (typeof spanContext !== "function") return;
|
|
1394
|
+
const context7 = spanContext.call(span);
|
|
1395
|
+
if (typeof (context7 == null ? void 0 : context7.spanId) === "string" && typeof context7.traceId === "string") {
|
|
1396
|
+
recordReplayExportedSpan(destination, context7.spanId, context7.traceId);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
function createReplayExporter(destination) {
|
|
1400
|
+
var _a;
|
|
1401
|
+
if (destination.kind === "workshop") {
|
|
1402
|
+
return new OTLPProtoTraceExporter({
|
|
1403
|
+
url: replayTraceUrl(destination.url)
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
return new OTLPProtoTraceExporter({
|
|
1407
|
+
url: replayTraceUrl(destination.url),
|
|
1408
|
+
headers: {
|
|
1409
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1410
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1411
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
var ReplayRoutingSpanExporter = class {
|
|
1416
|
+
constructor(normal, replayExporter = createReplayExporter) {
|
|
1417
|
+
this.normal = normal;
|
|
1418
|
+
this.replayExporter = replayExporter;
|
|
1419
|
+
}
|
|
1420
|
+
export(spans, resultCallback) {
|
|
1421
|
+
const replayGroups = /* @__PURE__ */ new Map();
|
|
1422
|
+
const normalSpans = [];
|
|
1423
|
+
for (const span of spans) {
|
|
1424
|
+
const destination = replayTraceDestinationFor(span);
|
|
1425
|
+
if (!destination) {
|
|
1426
|
+
normalSpans.push(span);
|
|
1427
|
+
continue;
|
|
1428
|
+
}
|
|
1429
|
+
const group = replayGroups.get(destination);
|
|
1430
|
+
recordExportedSpan(destination, span);
|
|
1431
|
+
if (group) group.push(span);
|
|
1432
|
+
else replayGroups.set(destination, [span]);
|
|
1433
|
+
}
|
|
1434
|
+
if (replayGroups.size === 0) {
|
|
1435
|
+
this.normal.export(spans, resultCallback);
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
let remaining = replayGroups.size + (normalSpans.length > 0 ? 1 : 0);
|
|
1439
|
+
let failed = false;
|
|
1440
|
+
let firstError;
|
|
1441
|
+
const finish = (result) => {
|
|
1442
|
+
if (result.code !== EXPORT_SUCCESS) {
|
|
1443
|
+
failed = true;
|
|
1444
|
+
firstError != null ? firstError : firstError = result.error;
|
|
1445
|
+
}
|
|
1446
|
+
remaining -= 1;
|
|
1447
|
+
if (remaining === 0) {
|
|
1448
|
+
resultCallback(
|
|
1449
|
+
firstError ? { code: EXPORT_FAILED, error: firstError } : { code: failed ? EXPORT_FAILED : EXPORT_SUCCESS }
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
};
|
|
1453
|
+
if (normalSpans.length > 0) {
|
|
1454
|
+
try {
|
|
1455
|
+
this.normal.export(normalSpans, finish);
|
|
1456
|
+
} catch (cause) {
|
|
1457
|
+
finish({
|
|
1458
|
+
code: EXPORT_FAILED,
|
|
1459
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
for (const [destination, replaySpans] of replayGroups) {
|
|
1464
|
+
let exporter;
|
|
1465
|
+
try {
|
|
1466
|
+
exporter = this.replayExporter(destination);
|
|
1467
|
+
} catch (cause) {
|
|
1468
|
+
finish({
|
|
1469
|
+
code: EXPORT_FAILED,
|
|
1470
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1471
|
+
});
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
try {
|
|
1475
|
+
exporter.export(replaySpans, (result) => {
|
|
1476
|
+
finish(result);
|
|
1477
|
+
void exporter.shutdown().catch(() => {
|
|
1478
|
+
});
|
|
1479
|
+
});
|
|
1480
|
+
} catch (cause) {
|
|
1481
|
+
finish({
|
|
1482
|
+
code: EXPORT_FAILED,
|
|
1483
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1484
|
+
});
|
|
1485
|
+
void exporter.shutdown().catch(() => {
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
forceFlush() {
|
|
1491
|
+
return this.normal.forceFlush ? this.normal.forceFlush() : Promise.resolve();
|
|
1492
|
+
}
|
|
1493
|
+
shutdown() {
|
|
1494
|
+
return this.normal.shutdown();
|
|
1495
|
+
}
|
|
1496
|
+
};
|
|
1497
|
+
|
|
1498
|
+
// src/tracing/multi-project.ts
|
|
1499
|
+
var PROJECT_ID_SPAN_ATTRIBUTE = "raindrop.project_id";
|
|
1500
|
+
var AUTH_HINT_SPAN_ATTRIBUTE = "raindrop.auth_hint";
|
|
1501
|
+
var EXPORT_SUCCESS2 = 0;
|
|
1502
|
+
var EXPORT_FAILED2 = 1;
|
|
1241
1503
|
var SPAN_STATUS_ERROR = 2;
|
|
1242
1504
|
function authHintForKey(writeKey) {
|
|
1243
1505
|
if (!writeKey) return void 0;
|
|
1244
1506
|
return createHash("sha256").update(writeKey, "utf8").digest("hex").slice(0, 8);
|
|
1245
1507
|
}
|
|
1246
|
-
var
|
|
1508
|
+
var STATE_KEY2 = /* @__PURE__ */ Symbol.for("raindrop.tracing.multiProjectState");
|
|
1247
1509
|
function getState() {
|
|
1248
1510
|
const holder = globalThis;
|
|
1249
|
-
let
|
|
1250
|
-
if (!
|
|
1251
|
-
|
|
1511
|
+
let state2 = holder[STATE_KEY2];
|
|
1512
|
+
if (!state2) {
|
|
1513
|
+
state2 = {
|
|
1252
1514
|
foreignClientSeen: false,
|
|
1253
1515
|
seenClientHints: /* @__PURE__ */ new Set(),
|
|
1254
1516
|
ownerAuthHint: void 0,
|
|
@@ -1258,29 +1520,29 @@ function getState() {
|
|
|
1258
1520
|
multiKeyWarned: false,
|
|
1259
1521
|
pendingMultiKeyWarning: false
|
|
1260
1522
|
};
|
|
1261
|
-
holder[
|
|
1523
|
+
holder[STATE_KEY2] = state2;
|
|
1262
1524
|
}
|
|
1263
|
-
return
|
|
1525
|
+
return state2;
|
|
1264
1526
|
}
|
|
1265
1527
|
function emitMultiKeyWarningOnce() {
|
|
1266
|
-
const
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
1528
|
+
const state2 = getState();
|
|
1529
|
+
if (state2.multiKeyWarned) return;
|
|
1530
|
+
state2.multiKeyWarned = true;
|
|
1531
|
+
state2.pendingMultiKeyWarning = false;
|
|
1270
1532
|
console.warn(
|
|
1271
1533
|
"[raindrop] Multiple API keys detected in one process. The OTel export guard now requires positive attribution: spans not bound to any client (no begin()/asCurrent()) are dropped, and spans bound to a non-owner key are dropped. Manual events are unaffected."
|
|
1272
1534
|
);
|
|
1273
1535
|
}
|
|
1274
1536
|
function registerClientKey(authHint, tracingEnabled = false) {
|
|
1275
1537
|
if (!authHint) return;
|
|
1276
|
-
const
|
|
1277
|
-
|
|
1278
|
-
if (
|
|
1279
|
-
|
|
1280
|
-
if (tracingEnabled ||
|
|
1538
|
+
const state2 = getState();
|
|
1539
|
+
state2.seenClientHints.add(authHint);
|
|
1540
|
+
if (state2.seenClientHints.size > 1) {
|
|
1541
|
+
state2.foreignClientSeen = true;
|
|
1542
|
+
if (tracingEnabled || state2.pipelineClaimed) {
|
|
1281
1543
|
emitMultiKeyWarningOnce();
|
|
1282
1544
|
} else {
|
|
1283
|
-
|
|
1545
|
+
state2.pendingMultiKeyWarning = true;
|
|
1284
1546
|
}
|
|
1285
1547
|
}
|
|
1286
1548
|
}
|
|
@@ -1304,6 +1566,9 @@ function stampSpan(span, projectId, authHint) {
|
|
|
1304
1566
|
function stampContextAttributes(span) {
|
|
1305
1567
|
try {
|
|
1306
1568
|
applySpanAttributeFrames(span, (key, value) => span.setAttribute(key, value));
|
|
1569
|
+
for (const [key, value] of Object.entries(evalScopeAttributes())) {
|
|
1570
|
+
span.setAttribute(key, value);
|
|
1571
|
+
}
|
|
1307
1572
|
} catch (e) {
|
|
1308
1573
|
}
|
|
1309
1574
|
}
|
|
@@ -1311,6 +1576,7 @@ var RaindropContextSpanProcessor = class {
|
|
|
1311
1576
|
onStart(span) {
|
|
1312
1577
|
try {
|
|
1313
1578
|
stampContextAttributes(span);
|
|
1579
|
+
rememberReplayTraceDestination(span);
|
|
1314
1580
|
const bound = currentRoutingBinding();
|
|
1315
1581
|
if (!bound) return;
|
|
1316
1582
|
stampSpan(span, bound.projectId, bound.authHint);
|
|
@@ -1371,7 +1637,7 @@ var GuardedSpanExporter = class {
|
|
|
1371
1637
|
} catch (e) {
|
|
1372
1638
|
if (foreignClientSeen()) {
|
|
1373
1639
|
this.warnDropped(spans.length);
|
|
1374
|
-
resultCallback({ code:
|
|
1640
|
+
resultCallback({ code: EXPORT_FAILED2 });
|
|
1375
1641
|
return;
|
|
1376
1642
|
}
|
|
1377
1643
|
this.inner.export(spans, resultCallback);
|
|
@@ -1381,7 +1647,7 @@ var GuardedSpanExporter = class {
|
|
|
1381
1647
|
this.warnDropped(dropped);
|
|
1382
1648
|
}
|
|
1383
1649
|
if (allowed.length === 0) {
|
|
1384
|
-
resultCallback({ code:
|
|
1650
|
+
resultCallback({ code: EXPORT_SUCCESS2 });
|
|
1385
1651
|
return;
|
|
1386
1652
|
}
|
|
1387
1653
|
this.inner.export(allowed, resultCallback);
|
|
@@ -1394,7 +1660,7 @@ var GuardedSpanExporter = class {
|
|
|
1394
1660
|
}
|
|
1395
1661
|
};
|
|
1396
1662
|
function buildGuardedExporter(baseUrl, headers, ownerAuthHint) {
|
|
1397
|
-
const inner = new
|
|
1663
|
+
const inner = new OTLPProtoTraceExporter2({
|
|
1398
1664
|
url: `${baseUrl}/v1/traces`,
|
|
1399
1665
|
headers
|
|
1400
1666
|
});
|
|
@@ -1404,23 +1670,23 @@ function pipelineOwnerHint() {
|
|
|
1404
1670
|
return getState().ownerAuthHint;
|
|
1405
1671
|
}
|
|
1406
1672
|
function claimPipeline(authHint, projectId) {
|
|
1407
|
-
const
|
|
1408
|
-
if (
|
|
1673
|
+
const state2 = getState();
|
|
1674
|
+
if (state2.pipelineClaimed) {
|
|
1409
1675
|
return false;
|
|
1410
1676
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
if (
|
|
1677
|
+
state2.pipelineClaimed = true;
|
|
1678
|
+
state2.ownerAuthHint = authHint;
|
|
1679
|
+
state2.ownerProjectId = projectId;
|
|
1680
|
+
if (state2.foreignClientSeen && state2.pendingMultiKeyWarning) {
|
|
1415
1681
|
emitMultiKeyWarningOnce();
|
|
1416
1682
|
}
|
|
1417
1683
|
return true;
|
|
1418
1684
|
}
|
|
1419
1685
|
function releasePipelineClaim() {
|
|
1420
|
-
const
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1686
|
+
const state2 = getState();
|
|
1687
|
+
state2.pipelineClaimed = false;
|
|
1688
|
+
state2.ownerAuthHint = void 0;
|
|
1689
|
+
state2.ownerProjectId = void 0;
|
|
1424
1690
|
}
|
|
1425
1691
|
function markTraceloopConfiguredWithoutClaim() {
|
|
1426
1692
|
getState().traceloopConfiguredWithoutClaim = true;
|
|
@@ -1436,9 +1702,9 @@ import { AnthropicInstrumentation } from "@traceloop/instrumentation-anthropic";
|
|
|
1436
1702
|
import { BedrockInstrumentation } from "@traceloop/instrumentation-bedrock";
|
|
1437
1703
|
import { ChromaDBInstrumentation } from "@traceloop/instrumentation-chromadb";
|
|
1438
1704
|
import { CohereInstrumentation } from "@traceloop/instrumentation-cohere";
|
|
1439
|
-
import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
|
|
1440
1705
|
import { LangChainInstrumentation } from "@traceloop/instrumentation-langchain";
|
|
1441
1706
|
import { LlamaIndexInstrumentation } from "@traceloop/instrumentation-llamaindex";
|
|
1707
|
+
import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
|
|
1442
1708
|
import { PineconeInstrumentation } from "@traceloop/instrumentation-pinecone";
|
|
1443
1709
|
import { QdrantInstrumentation } from "@traceloop/instrumentation-qdrant";
|
|
1444
1710
|
import { TogetherInstrumentation } from "@traceloop/instrumentation-together";
|
|
@@ -1446,920 +1712,954 @@ import {
|
|
|
1446
1712
|
AIPlatformInstrumentation,
|
|
1447
1713
|
VertexAIInstrumentation
|
|
1448
1714
|
} from "@traceloop/instrumentation-vertexai";
|
|
1715
|
+
import { WeakValueMap } from "weakref";
|
|
1449
1716
|
|
|
1450
|
-
// src/tracing/
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
DiagLogLevel,
|
|
1454
|
-
context,
|
|
1455
|
-
diag,
|
|
1456
|
-
trace
|
|
1457
|
-
} from "@opentelemetry/api";
|
|
1458
|
-
import { suppressTracing } from "@opentelemetry/core";
|
|
1459
|
-
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
1460
|
-
import { registerInstrumentations } from "@opentelemetry/instrumentation";
|
|
1461
|
-
import * as resourceModule from "@opentelemetry/resources";
|
|
1462
|
-
import {
|
|
1463
|
-
BatchSpanProcessor,
|
|
1464
|
-
SimpleSpanProcessor
|
|
1465
|
-
} from "@opentelemetry/sdk-trace-base";
|
|
1466
|
-
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
1467
|
-
import {
|
|
1468
|
-
CONTEXT_KEY_ALLOW_TRACE_CONTENT,
|
|
1469
|
-
SpanAttributes,
|
|
1470
|
-
TraceloopSpanKindValues
|
|
1471
|
-
} from "@traceloop/ai-semantic-conventions";
|
|
1472
|
-
var ALL_INSTRUMENTATION_LIBRARIES = "all";
|
|
1473
|
-
var TRACER_NAME = "@traceloop/node-server-sdk";
|
|
1474
|
-
var WORKFLOW_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.workflowName");
|
|
1475
|
-
var ENTITY_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.entityName");
|
|
1476
|
-
var ASSOCIATION_PROPERTIES_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.associationProperties");
|
|
1477
|
-
var INSTRUMENTATION_LIBRARIES = [
|
|
1478
|
-
"ai",
|
|
1479
|
-
"@traceloop/node-server-sdk",
|
|
1480
|
-
"@traceloop/instrumentation-openai",
|
|
1481
|
-
"@traceloop/instrumentation-langchain",
|
|
1482
|
-
"@traceloop/instrumentation-chroma",
|
|
1483
|
-
"@traceloop/instrumentation-chromadb",
|
|
1484
|
-
"@traceloop/instrumentation-anthropic",
|
|
1485
|
-
"@traceloop/instrumentation-llamaindex",
|
|
1486
|
-
"@traceloop/instrumentation-vertexai",
|
|
1487
|
-
"@traceloop/instrumentation-bedrock",
|
|
1488
|
-
"@traceloop/instrumentation-cohere",
|
|
1489
|
-
"@traceloop/instrumentation-pinecone",
|
|
1490
|
-
"@traceloop/instrumentation-qdrant",
|
|
1491
|
-
"@traceloop/instrumentation-together",
|
|
1492
|
-
TRACER_NAME,
|
|
1493
|
-
"traceloop.tracer"
|
|
1494
|
-
];
|
|
1495
|
-
var AI_GENERATE_TEXT = "ai.generateText.doGenerate";
|
|
1496
|
-
var AI_STREAM_TEXT = "ai.streamText.doStream";
|
|
1497
|
-
var AI_RESPONSE_TEXT = "ai.response.text";
|
|
1498
|
-
var AI_PROMPT_MESSAGES = "ai.prompt.messages";
|
|
1499
|
-
var AI_PROMPT_TOKENS = "ai.usage.promptTokens";
|
|
1500
|
-
var AI_COMPLETION_TOKENS = "ai.usage.completionTokens";
|
|
1501
|
-
var AI_MODEL_PROVIDER = "ai.model.provider";
|
|
1502
|
-
var STATE_KEY2 = /* @__PURE__ */ Symbol.for("raindrop.otelCore.state");
|
|
1503
|
-
function getState2() {
|
|
1504
|
-
var _a;
|
|
1505
|
-
const holder = globalThis;
|
|
1506
|
-
(_a = holder[STATE_KEY2]) != null ? _a : holder[STATE_KEY2] = {};
|
|
1507
|
-
return holder[STATE_KEY2];
|
|
1717
|
+
// src/tracing/direct/http.ts
|
|
1718
|
+
function wait2(ms) {
|
|
1719
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1508
1720
|
}
|
|
1509
|
-
function
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
for (const pair of value.split(",")) {
|
|
1513
|
-
const separator = pair.indexOf("=");
|
|
1514
|
-
if (separator <= 0) continue;
|
|
1515
|
-
try {
|
|
1516
|
-
const key = decodeURIComponent(pair.slice(0, separator).trim());
|
|
1517
|
-
const val = decodeURIComponent(pair.slice(separator + 1).trim());
|
|
1518
|
-
if (key && val) headers[key] = val;
|
|
1519
|
-
} catch (e) {
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
return headers;
|
|
1721
|
+
function formatEndpoint2(endpoint) {
|
|
1722
|
+
if (!endpoint) return void 0;
|
|
1723
|
+
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
1523
1724
|
}
|
|
1524
|
-
function
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1725
|
+
function parseRetryAfter2(headers) {
|
|
1726
|
+
var _a;
|
|
1727
|
+
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
1728
|
+
if (!value) return void 0;
|
|
1729
|
+
const asNumber = Number(value);
|
|
1730
|
+
if (!Number.isNaN(asNumber)) return asNumber * 1e3;
|
|
1731
|
+
const asDate = new Date(value).getTime();
|
|
1732
|
+
if (!Number.isNaN(asDate)) {
|
|
1733
|
+
const delta = asDate - Date.now();
|
|
1734
|
+
return delta > 0 ? delta : 0;
|
|
1530
1735
|
}
|
|
1736
|
+
return void 0;
|
|
1531
1737
|
}
|
|
1532
|
-
function
|
|
1533
|
-
if ("
|
|
1534
|
-
const
|
|
1535
|
-
if (typeof
|
|
1738
|
+
function getRetryDelayMs2(attemptNumber, previousError) {
|
|
1739
|
+
if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
|
|
1740
|
+
const v = previousError.retryAfterMs;
|
|
1741
|
+
if (typeof v === "number") return Math.min(Math.max(0, v), MAX_RETRY_DELAY_MS);
|
|
1536
1742
|
}
|
|
1537
|
-
|
|
1743
|
+
if (attemptNumber <= 1) return 0;
|
|
1744
|
+
const base = 500;
|
|
1745
|
+
const factor = Math.pow(2, attemptNumber - 2);
|
|
1746
|
+
return Math.min(base * factor, MAX_RETRY_DELAY_MS);
|
|
1538
1747
|
}
|
|
1539
|
-
function
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
}
|
|
1748
|
+
async function withRetry2(operation, opName, opts) {
|
|
1749
|
+
let lastError = void 0;
|
|
1750
|
+
for (let attemptNumber = 1; attemptNumber <= opts.maxAttempts; attemptNumber++) {
|
|
1751
|
+
if (attemptNumber > 1) {
|
|
1752
|
+
const delay = getRetryDelayMs2(attemptNumber, lastError);
|
|
1753
|
+
if (opts.debug) {
|
|
1754
|
+
console.warn(
|
|
1755
|
+
`[raindrop] ${opName} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
if (delay > 0) await wait2(delay);
|
|
1759
|
+
} else if (opts.debug) {
|
|
1760
|
+
console.log(`[raindrop] ${opName} attempt ${attemptNumber}/${opts.maxAttempts}`);
|
|
1549
1761
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
return detected;
|
|
1762
|
+
try {
|
|
1763
|
+
return await operation();
|
|
1764
|
+
} catch (err) {
|
|
1765
|
+
lastError = err;
|
|
1766
|
+
if (opts.debug) {
|
|
1767
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1768
|
+
console.warn(
|
|
1769
|
+
`[raindrop] ${opName} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
|
|
1770
|
+
);
|
|
1560
1771
|
}
|
|
1772
|
+
if (attemptNumber === opts.maxAttempts) break;
|
|
1561
1773
|
}
|
|
1562
|
-
} catch (e) {
|
|
1563
|
-
}
|
|
1564
|
-
return void 0;
|
|
1565
|
-
}
|
|
1566
|
-
function logLevel(level) {
|
|
1567
|
-
switch (level) {
|
|
1568
|
-
case "debug":
|
|
1569
|
-
return DiagLogLevel.DEBUG;
|
|
1570
|
-
case "info":
|
|
1571
|
-
return DiagLogLevel.INFO;
|
|
1572
|
-
case "warn":
|
|
1573
|
-
return DiagLogLevel.WARN;
|
|
1574
|
-
default:
|
|
1575
|
-
return DiagLogLevel.ERROR;
|
|
1576
1774
|
}
|
|
1775
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
1577
1776
|
}
|
|
1578
|
-
function
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
if (
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
}
|
|
1605
|
-
});
|
|
1777
|
+
async function postJson2(url, body, headers, opts) {
|
|
1778
|
+
var _a;
|
|
1779
|
+
const opName = `POST ${redactUrlForLog(url)}`;
|
|
1780
|
+
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1781
|
+
await withRetry2(
|
|
1782
|
+
async () => {
|
|
1783
|
+
const resp = await runWithTracingSuppressed(
|
|
1784
|
+
() => fetch(url, {
|
|
1785
|
+
method: "POST",
|
|
1786
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
1787
|
+
headers: {
|
|
1788
|
+
"Content-Type": "application/json",
|
|
1789
|
+
...headers
|
|
1790
|
+
},
|
|
1791
|
+
body: JSON.stringify(body),
|
|
1792
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1793
|
+
})
|
|
1794
|
+
);
|
|
1795
|
+
if (!resp.ok) {
|
|
1796
|
+
const text = await resp.text().catch(() => "");
|
|
1797
|
+
const err = new Error(
|
|
1798
|
+
`HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
|
|
1799
|
+
);
|
|
1800
|
+
const retryAfterMs = parseRetryAfter2(resp.headers);
|
|
1801
|
+
if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
|
|
1802
|
+
throw err;
|
|
1606
1803
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1804
|
+
},
|
|
1805
|
+
opName,
|
|
1806
|
+
opts
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
// src/tracing/direct/ids.ts
|
|
1811
|
+
function getCrypto2() {
|
|
1812
|
+
const c = globalThis.crypto;
|
|
1813
|
+
return c;
|
|
1814
|
+
}
|
|
1815
|
+
function randomBytes2(length) {
|
|
1816
|
+
const cryptoObj = getCrypto2();
|
|
1817
|
+
const out = new Uint8Array(length);
|
|
1818
|
+
if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
|
|
1819
|
+
cryptoObj.getRandomValues(out);
|
|
1820
|
+
return out;
|
|
1614
1821
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1822
|
+
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
1823
|
+
return out;
|
|
1824
|
+
}
|
|
1825
|
+
function base64Encode2(bytes) {
|
|
1826
|
+
const maybeBuffer = globalThis.Buffer;
|
|
1827
|
+
if (maybeBuffer) {
|
|
1828
|
+
return maybeBuffer.from(bytes).toString("base64");
|
|
1618
1829
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] = Number(prompt) + Number(completion);
|
|
1830
|
+
let binary = "";
|
|
1831
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
1832
|
+
binary += String.fromCharCode(bytes[i2]);
|
|
1623
1833
|
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1834
|
+
const btoaFn = globalThis.btoa;
|
|
1835
|
+
if (typeof btoaFn === "function") return btoaFn(binary);
|
|
1836
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1837
|
+
let out = "";
|
|
1838
|
+
let i = 0;
|
|
1839
|
+
while (i < binary.length) {
|
|
1840
|
+
const c1 = binary.charCodeAt(i++) & 255;
|
|
1841
|
+
const c2 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1842
|
+
const c3 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1843
|
+
const e1 = c1 >> 2;
|
|
1844
|
+
const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
|
|
1845
|
+
const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
|
|
1846
|
+
const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
|
|
1847
|
+
out += alphabet.charAt(e1);
|
|
1848
|
+
out += alphabet.charAt(e2);
|
|
1849
|
+
out += e3 === 64 ? "=" : alphabet.charAt(e3);
|
|
1850
|
+
out += e4 === 64 ? "=" : alphabet.charAt(e4);
|
|
1628
1851
|
}
|
|
1629
|
-
|
|
1630
|
-
configurable: true,
|
|
1631
|
-
value: names[span.name],
|
|
1632
|
-
writable: true
|
|
1633
|
-
});
|
|
1634
|
-
return span;
|
|
1852
|
+
return out;
|
|
1635
1853
|
}
|
|
1636
|
-
function
|
|
1637
|
-
|
|
1638
|
-
if (
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1854
|
+
function base64ToHex2(base64) {
|
|
1855
|
+
const maybeBuffer = globalThis.Buffer;
|
|
1856
|
+
if (maybeBuffer) {
|
|
1857
|
+
return maybeBuffer.from(base64, "base64").toString("hex");
|
|
1858
|
+
}
|
|
1859
|
+
const atobFn = globalThis.atob;
|
|
1860
|
+
if (typeof atobFn === "function") {
|
|
1861
|
+
const binary = atobFn(base64);
|
|
1862
|
+
let hex = "";
|
|
1863
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1864
|
+
hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
|
|
1642
1865
|
}
|
|
1866
|
+
return hex;
|
|
1643
1867
|
}
|
|
1644
|
-
|
|
1868
|
+
throw new Error("No base64 decoder available in this runtime");
|
|
1645
1869
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1870
|
+
|
|
1871
|
+
// src/tracing/direct/otlp.ts
|
|
1872
|
+
var libraryVersion = package_default.version;
|
|
1873
|
+
var SERVICE_NAME = "raindrop-ai";
|
|
1874
|
+
function attrString2(key, value) {
|
|
1875
|
+
if (value === void 0) return void 0;
|
|
1876
|
+
return { key, value: { stringValue: value } };
|
|
1648
1877
|
}
|
|
1649
|
-
function
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
if (((_a = getState2().configuration) == null ? void 0 : _a.traceContent) === false) return false;
|
|
1654
|
-
return (process.env.TRACELOOP_TRACE_CONTENT || "true").toLowerCase() !== "false";
|
|
1878
|
+
function attrInt2(key, value) {
|
|
1879
|
+
if (value === void 0) return void 0;
|
|
1880
|
+
if (!Number.isFinite(value)) return void 0;
|
|
1881
|
+
return { key, value: { intValue: String(Math.trunc(value)) } };
|
|
1655
1882
|
}
|
|
1656
|
-
function
|
|
1657
|
-
const
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1883
|
+
function buildOtlpSpan2(args) {
|
|
1884
|
+
const attrs = args.attributes.filter((x) => x !== void 0);
|
|
1885
|
+
const span = {
|
|
1886
|
+
traceId: args.ids.traceIdB64,
|
|
1887
|
+
spanId: args.ids.spanIdB64,
|
|
1888
|
+
name: args.name,
|
|
1889
|
+
startTimeUnixNano: args.startTimeUnixNano,
|
|
1890
|
+
endTimeUnixNano: args.endTimeUnixNano
|
|
1891
|
+
};
|
|
1892
|
+
if (args.ids.parentSpanIdB64) span.parentSpanId = args.ids.parentSpanIdB64;
|
|
1893
|
+
if (attrs.length) span.attributes = attrs;
|
|
1894
|
+
if (args.status) span.status = args.status;
|
|
1895
|
+
return span;
|
|
1896
|
+
}
|
|
1897
|
+
function buildExportTraceServiceRequest2(spans) {
|
|
1898
|
+
return {
|
|
1899
|
+
resourceSpans: [
|
|
1900
|
+
{
|
|
1901
|
+
resource: {
|
|
1902
|
+
attributes: [{ key: "service.name", value: { stringValue: SERVICE_NAME } }]
|
|
1903
|
+
},
|
|
1904
|
+
scopeSpans: [
|
|
1905
|
+
{
|
|
1906
|
+
scope: { name: SERVICE_NAME, version: libraryVersion },
|
|
1907
|
+
spans
|
|
1908
|
+
}
|
|
1909
|
+
]
|
|
1667
1910
|
}
|
|
1668
|
-
|
|
1911
|
+
]
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
// src/tracing/direct/context.ts
|
|
1916
|
+
import { context, isValidSpanId, isValidTraceId, trace } from "@opentelemetry/api";
|
|
1917
|
+
var INVALID_TRACE_ID = "00000000000000000000000000000000";
|
|
1918
|
+
var INVALID_SPAN_ID = "0000000000000000";
|
|
1919
|
+
function hexToBase64(hex) {
|
|
1920
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
1921
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
1922
|
+
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
1669
1923
|
}
|
|
1924
|
+
return base64Encode2(bytes);
|
|
1670
1925
|
}
|
|
1671
|
-
function
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
const originalOnStart = processor.onStart.bind(processor);
|
|
1679
|
-
const originalOnEnd = processor.onEnd.bind(processor);
|
|
1680
|
-
processor.onStart = (span, parentContext) => {
|
|
1681
|
-
try {
|
|
1682
|
-
enrichStart(span);
|
|
1683
|
-
originalOnStart(span, parentContext);
|
|
1684
|
-
} catch (e) {
|
|
1685
|
-
}
|
|
1686
|
-
};
|
|
1687
|
-
processor.onEnd = (span) => {
|
|
1688
|
-
var _a2;
|
|
1689
|
-
let outgoing = span;
|
|
1690
|
-
try {
|
|
1691
|
-
const allowed = options.allowedInstrumentationLibraries;
|
|
1692
|
-
if (allowed !== ALL_INSTRUMENTATION_LIBRARIES && ![...INSTRUMENTATION_LIBRARIES, ...allowed != null ? allowed : []].includes((_a2 = scopeName(span)) != null ? _a2 : "")) {
|
|
1693
|
-
return;
|
|
1694
|
-
}
|
|
1695
|
-
outgoing = transformAiSdkSpan(span);
|
|
1696
|
-
} catch (e) {
|
|
1697
|
-
}
|
|
1698
|
-
try {
|
|
1699
|
-
originalOnEnd(outgoing);
|
|
1700
|
-
} catch (e) {
|
|
1701
|
-
}
|
|
1926
|
+
function getExplicitTraceContext(traceId, parentSpanId) {
|
|
1927
|
+
if (!traceId || !parentSpanId || !isValidTraceId(traceId) || !isValidSpanId(parentSpanId)) {
|
|
1928
|
+
return void 0;
|
|
1929
|
+
}
|
|
1930
|
+
return {
|
|
1931
|
+
traceIdB64: hexToBase64(traceId),
|
|
1932
|
+
parentSpanIdB64: hexToBase64(parentSpanId)
|
|
1702
1933
|
};
|
|
1703
|
-
return processor;
|
|
1704
1934
|
}
|
|
1705
|
-
function
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
if (
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
1717
|
-
});
|
|
1718
|
-
const serviceResource = createResource({
|
|
1719
|
-
"service.name": options.appName || process.env.npm_package_name || "unknown_service"
|
|
1720
|
-
});
|
|
1721
|
-
const detectedResource = detectRuntimeResource();
|
|
1722
|
-
state.provider = new NodeTracerProvider({
|
|
1723
|
-
// Detected attributes win over the configured resource, matching
|
|
1724
|
-
// sdk-node's `this._resource.merge(detectResourcesSync(...))` so
|
|
1725
|
-
// OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES can still override appName.
|
|
1726
|
-
resource: detectedResource ? serviceResource.merge(detectedResource) : serviceResource,
|
|
1727
|
-
spanProcessors: [state.defaultProcessor, ...options.processor ? [options.processor] : []]
|
|
1728
|
-
});
|
|
1729
|
-
state.provider.register({
|
|
1730
|
-
contextManager: options.contextManager,
|
|
1731
|
-
propagator: options.propagator
|
|
1732
|
-
});
|
|
1733
|
-
const instrumentations = (_a = options.instrumentations) != null ? _a : [];
|
|
1734
|
-
if (contentCaptureDisabled(options)) {
|
|
1735
|
-
for (const instrumentation of instrumentations) {
|
|
1736
|
-
try {
|
|
1737
|
-
const config = {
|
|
1738
|
-
...instrumentation.getConfig(),
|
|
1739
|
-
traceContent: false
|
|
1740
|
-
};
|
|
1741
|
-
instrumentation.setConfig(config);
|
|
1742
|
-
} catch (e) {
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
registerInstrumentations({ instrumentations });
|
|
1935
|
+
function getActiveTraceContext() {
|
|
1936
|
+
const activeSpan = trace.getSpan(context.active());
|
|
1937
|
+
if (!activeSpan) return {};
|
|
1938
|
+
const spanContext = activeSpan.spanContext();
|
|
1939
|
+
const traceIdHex = spanContext.traceId;
|
|
1940
|
+
const spanIdHex = spanContext.spanId;
|
|
1941
|
+
if (traceIdHex === INVALID_TRACE_ID) return {};
|
|
1942
|
+
return {
|
|
1943
|
+
traceIdB64: hexToBase64(traceIdHex),
|
|
1944
|
+
parentSpanIdB64: spanIdHex !== INVALID_SPAN_ID ? hexToBase64(spanIdHex) : void 0
|
|
1945
|
+
};
|
|
1747
1946
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
await ((_a = state.provider) == null ? void 0 : _a.forceFlush());
|
|
1753
|
-
await ((_b = state.defaultProcessor) == null ? void 0 : _b.forceFlush());
|
|
1754
|
-
} catch (e) {
|
|
1755
|
-
}
|
|
1947
|
+
|
|
1948
|
+
// src/tracing/direct/shipper.ts
|
|
1949
|
+
function serializeAssociationValue(value) {
|
|
1950
|
+
return stringifyBounded(value);
|
|
1756
1951
|
}
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1952
|
+
var DirectTraceShipper = class {
|
|
1953
|
+
constructor(opts) {
|
|
1954
|
+
this.queue = [];
|
|
1955
|
+
this.inFlight = /* @__PURE__ */ new Set();
|
|
1956
|
+
/**
|
|
1957
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
1958
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
1959
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
1960
|
+
* retry schedule.
|
|
1961
|
+
*/
|
|
1962
|
+
this.hasShutdown = false;
|
|
1963
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1964
|
+
this.writeKey = opts.writeKey;
|
|
1965
|
+
this.baseUrl = (_a = formatEndpoint2(opts.endpoint)) != null ? _a : "https://api.raindrop.ai/v1/";
|
|
1966
|
+
this.enabled = (_b = opts.enabled) != null ? _b : true;
|
|
1967
|
+
this.cloudEnabled = (_c = opts.cloudEnabled) != null ? _c : true;
|
|
1968
|
+
this.debug = opts.debug;
|
|
1969
|
+
this.projectId = opts.projectId;
|
|
1970
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1971
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1972
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1973
|
+
const resolved = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl);
|
|
1974
|
+
if (resolved && resolved !== this.baseUrl) {
|
|
1975
|
+
this.localDebuggerUrl = resolved;
|
|
1976
|
+
}
|
|
1777
1977
|
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
safeStringify(input.length === 1 && input[0] !== null && typeof input[0] === "object" && !(input[0] instanceof Map) ? { args: [], kwargs: input[0] } : { args: input, kwargs: {} })
|
|
1794
|
-
);
|
|
1795
|
-
}
|
|
1796
|
-
} catch (e) {
|
|
1978
|
+
/**
|
|
1979
|
+
* Build and enqueue an OTLP span for a trackTool call.
|
|
1980
|
+
*
|
|
1981
|
+
* Reads the active OTEL context if traceId/parentSpanId are not provided,
|
|
1982
|
+
* so spans still appear as children in the trace tree.
|
|
1983
|
+
*/
|
|
1984
|
+
sendSpan(params) {
|
|
1985
|
+
var _a, _b, _c;
|
|
1986
|
+
if (!this.enabled) return;
|
|
1987
|
+
let traceIdB64 = params.traceId;
|
|
1988
|
+
let parentSpanIdB64 = params.parentSpanId;
|
|
1989
|
+
if (!traceIdB64) {
|
|
1990
|
+
const activeCtx = getActiveTraceContext();
|
|
1991
|
+
traceIdB64 = activeCtx.traceIdB64;
|
|
1992
|
+
parentSpanIdB64 = activeCtx.parentSpanIdB64;
|
|
1797
1993
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
result = fn(...args);
|
|
1802
|
-
} catch (error) {
|
|
1803
|
-
try {
|
|
1804
|
-
span.end();
|
|
1805
|
-
} catch (e) {
|
|
1806
|
-
}
|
|
1807
|
-
throw error;
|
|
1994
|
+
const spanIdB64 = (_a = params.spanId) != null ? _a : base64Encode2(randomBytes2(8));
|
|
1995
|
+
if (!traceIdB64) {
|
|
1996
|
+
traceIdB64 = base64Encode2(randomBytes2(16));
|
|
1808
1997
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1998
|
+
const startTimeUnixNano = String(params.startTimeMs * 1e6);
|
|
1999
|
+
const endTimeUnixNano = String(params.endTimeMs * 1e6);
|
|
2000
|
+
const attributes = [
|
|
2001
|
+
// Required: passes hasAIOperation() filter in backend (parseSpan.ts)
|
|
2002
|
+
attrString2("traceloop.span.kind", (_b = params.spanKind) != null ? _b : "tool"),
|
|
2003
|
+
// Parsed by backend for input/output payloads
|
|
2004
|
+
attrString2("traceloop.entity.input", params.input),
|
|
2005
|
+
attrString2("traceloop.entity.output", params.output),
|
|
2006
|
+
// Duration tracking
|
|
2007
|
+
attrInt2("traceloop.entity.duration_ms", params.durationMs),
|
|
2008
|
+
// Per-span project routing: the ingest boundary routes on this attribute
|
|
2009
|
+
// (org-validated) and falls back to the request's project header. Direct
|
|
2010
|
+
// spans ship on this instance's own key, so no cross-key auth hint.
|
|
2011
|
+
attrString2(PROJECT_ID_SPAN_ATTRIBUTE, this.projectId)
|
|
2012
|
+
];
|
|
2013
|
+
for (const [key, value] of Object.entries(params.properties)) {
|
|
2014
|
+
if (value === void 0) {
|
|
2015
|
+
continue;
|
|
2016
|
+
}
|
|
2017
|
+
attributes.push(
|
|
2018
|
+
attrString2(`traceloop.association.properties.${key}`, serializeAssociationValue(value))
|
|
1826
2019
|
);
|
|
1827
2020
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
2021
|
+
const spanIdentity = { spanIdB64 };
|
|
2022
|
+
claimSpanForFrames(spanIdentity);
|
|
2023
|
+
for (const [key, value] of Object.entries({
|
|
2024
|
+
...currentSpanAttributes(),
|
|
2025
|
+
...params.attributes,
|
|
2026
|
+
// Last, so neither a bound frame nor an explicit caller attribute can
|
|
2027
|
+
// shadow the replay row a span belongs to.
|
|
2028
|
+
...evalScopeAttributes()
|
|
2029
|
+
})) {
|
|
2030
|
+
attributes.push(attrString2(key, value));
|
|
1832
2031
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
2032
|
+
attributes.push(...(_c = params.otlpAttributes) != null ? _c : []);
|
|
2033
|
+
let status;
|
|
2034
|
+
if (params.error) {
|
|
2035
|
+
status = { code: 2, message: params.error };
|
|
2036
|
+
markErrorSpanSeen(spanIdentity);
|
|
2037
|
+
} else {
|
|
2038
|
+
status = {
|
|
2039
|
+
code: 1
|
|
2040
|
+
/* STATUS_CODE_OK */
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
const span = buildOtlpSpan2({
|
|
2044
|
+
ids: {
|
|
2045
|
+
traceIdB64,
|
|
2046
|
+
spanIdB64,
|
|
2047
|
+
parentSpanIdB64
|
|
2048
|
+
},
|
|
2049
|
+
name: params.name,
|
|
2050
|
+
startTimeUnixNano,
|
|
2051
|
+
endTimeUnixNano,
|
|
2052
|
+
attributes,
|
|
2053
|
+
status
|
|
2054
|
+
});
|
|
2055
|
+
const replayDestination = currentReplayTraceDestination();
|
|
2056
|
+
recordReplayExportedSpan(
|
|
2057
|
+
replayDestination,
|
|
2058
|
+
base64ToHex2(span.spanId),
|
|
2059
|
+
base64ToHex2(span.traceId)
|
|
1840
2060
|
);
|
|
1841
|
-
|
|
1842
|
-
if (
|
|
1843
|
-
|
|
2061
|
+
const mirrorUrl = (replayDestination == null ? void 0 : replayDestination.kind) === "workshop" ? replayDestination.url : replayDestination ? void 0 : this.localDebuggerUrl;
|
|
2062
|
+
if (mirrorUrl) {
|
|
2063
|
+
const body = buildExportTraceServiceRequest2([span]);
|
|
2064
|
+
const mirror = mirrorTraceExportToLocalDebugger(body, {
|
|
2065
|
+
baseUrl: mirrorUrl,
|
|
2066
|
+
debug: false,
|
|
2067
|
+
sdkName: "js-sdk"
|
|
2068
|
+
});
|
|
2069
|
+
this.inFlight.add(mirror);
|
|
2070
|
+
void mirror.finally(() => this.inFlight.delete(mirror));
|
|
2071
|
+
}
|
|
2072
|
+
this.enqueue({ span, replayDestination });
|
|
2073
|
+
if (this.debug) {
|
|
2074
|
+
console.log(`[raindrop] direct shipper: enqueued span "${params.name}"`);
|
|
2075
|
+
}
|
|
1844
2076
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
return withEntity(TraceloopSpanKindValues.TOOL, config, fn, args);
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
// src/tracing/tracer-core.ts
|
|
1854
|
-
import { WeakValueMap } from "weakref";
|
|
1855
|
-
|
|
1856
|
-
// src/tracing/direct/http.ts
|
|
1857
|
-
function wait2(ms) {
|
|
1858
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1859
|
-
}
|
|
1860
|
-
function formatEndpoint2(endpoint) {
|
|
1861
|
-
if (!endpoint) return void 0;
|
|
1862
|
-
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
1863
|
-
}
|
|
1864
|
-
function parseRetryAfter2(headers) {
|
|
1865
|
-
var _a;
|
|
1866
|
-
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
1867
|
-
if (!value) return void 0;
|
|
1868
|
-
const asNumber = Number(value);
|
|
1869
|
-
if (!Number.isNaN(asNumber)) return asNumber * 1e3;
|
|
1870
|
-
const asDate = new Date(value).getTime();
|
|
1871
|
-
if (!Number.isNaN(asDate)) {
|
|
1872
|
-
const delta = asDate - Date.now();
|
|
1873
|
-
return delta > 0 ? delta : 0;
|
|
2077
|
+
sendToolSpan(params) {
|
|
2078
|
+
this.sendSpan({
|
|
2079
|
+
...params,
|
|
2080
|
+
spanKind: "tool"
|
|
2081
|
+
});
|
|
1874
2082
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
2083
|
+
enqueue(queued) {
|
|
2084
|
+
if (!this.enabled) return;
|
|
2085
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
2086
|
+
this.queue.shift();
|
|
2087
|
+
}
|
|
2088
|
+
this.queue.push(queued);
|
|
2089
|
+
if (this.queue.length >= this.maxBatchSize) {
|
|
2090
|
+
void this.flush().catch(() => {
|
|
2091
|
+
});
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
if (!this.timer) {
|
|
2095
|
+
this.timer = setTimeout(() => {
|
|
2096
|
+
this.timer = void 0;
|
|
2097
|
+
void this.flush().catch(() => {
|
|
2098
|
+
});
|
|
2099
|
+
}, this.flushIntervalMs);
|
|
2100
|
+
}
|
|
1881
2101
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
const
|
|
1892
|
-
if (opts
|
|
1893
|
-
|
|
1894
|
-
|
|
2102
|
+
async flush() {
|
|
2103
|
+
var _a;
|
|
2104
|
+
if (!this.enabled) return;
|
|
2105
|
+
if (this.timer) {
|
|
2106
|
+
clearTimeout(this.timer);
|
|
2107
|
+
this.timer = void 0;
|
|
2108
|
+
}
|
|
2109
|
+
while (this.queue.length > 0) {
|
|
2110
|
+
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
2111
|
+
const opts = this.requestOpts();
|
|
2112
|
+
if (!opts) {
|
|
2113
|
+
rateLimitedLog(
|
|
2114
|
+
"js-sdk.direct.shutdown_deadline",
|
|
2115
|
+
() => console.warn(
|
|
2116
|
+
`[raindrop] direct: shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
2117
|
+
)
|
|
1895
2118
|
);
|
|
2119
|
+
continue;
|
|
1896
2120
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
2121
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2122
|
+
for (const queued of batch) {
|
|
2123
|
+
const spans = groups.get(queued.replayDestination);
|
|
2124
|
+
if (spans) spans.push(queued.span);
|
|
2125
|
+
else groups.set(queued.replayDestination, [queued.span]);
|
|
2126
|
+
}
|
|
2127
|
+
for (const [replayDestination, spans] of groups) {
|
|
2128
|
+
if (!replayDestination && !this.cloudEnabled) continue;
|
|
2129
|
+
if ((replayDestination == null ? void 0 : replayDestination.kind) === "workshop") continue;
|
|
2130
|
+
const body = buildExportTraceServiceRequest2(spans);
|
|
2131
|
+
const url = replayDestination ? replayTraceUrl(replayDestination.url) : `${this.baseUrl}traces`;
|
|
2132
|
+
const headers = replayDestination ? {
|
|
2133
|
+
Authorization: `Bearer ${replayDestination.apiKey}`,
|
|
2134
|
+
"X-Raindrop-Replay-Id": replayDestination.replayId,
|
|
2135
|
+
"X-Raindrop-Project-Id": (_a = replayDestination.projectId) != null ? _a : "default"
|
|
2136
|
+
} : { Authorization: `Bearer ${this.writeKey}`, ...projectIdHeaders(this.projectId) };
|
|
2137
|
+
const p = postJson2(url, body, headers, opts);
|
|
2138
|
+
this.inFlight.add(p);
|
|
2139
|
+
try {
|
|
2140
|
+
try {
|
|
2141
|
+
await p;
|
|
2142
|
+
if (this.debug) console.log(`[raindrop] direct: sent ${spans.length} spans`);
|
|
2143
|
+
} catch (err) {
|
|
2144
|
+
if (this.debug) {
|
|
2145
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2146
|
+
console.warn(`[raindrop] direct: failed to send spans (dropping): ${msg}`);
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
} finally {
|
|
2150
|
+
this.inFlight.delete(p);
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Retry/timeout options for one batch POST, honoring the shutdown budget:
|
|
2157
|
+
* outside shutdown, the normal 3-attempt schedule; during shutdown, a
|
|
2158
|
+
* single attempt clamped to the remaining window; `null` once the window
|
|
2159
|
+
* is exhausted (caller drops the batch). After shutdown() returns,
|
|
2160
|
+
* stragglers run as a single short attempt.
|
|
2161
|
+
*/
|
|
2162
|
+
requestOpts() {
|
|
2163
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
2164
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
2165
|
+
if (remainingMs <= 0) return null;
|
|
2166
|
+
return {
|
|
2167
|
+
maxAttempts: 1,
|
|
2168
|
+
debug: this.debug,
|
|
2169
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
2170
|
+
};
|
|
1900
2171
|
}
|
|
2172
|
+
if (this.hasShutdown) {
|
|
2173
|
+
return { maxAttempts: 1, debug: this.debug, timeoutMs: POST_SHUTDOWN_TIMEOUT_MS };
|
|
2174
|
+
}
|
|
2175
|
+
return { maxAttempts: 3, debug: this.debug };
|
|
2176
|
+
}
|
|
2177
|
+
async shutdown() {
|
|
2178
|
+
this.hasShutdown = true;
|
|
2179
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
1901
2180
|
try {
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
if (opts.debug) {
|
|
1906
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1907
|
-
console.warn(
|
|
1908
|
-
`[raindrop] ${opName} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
|
|
1909
|
-
);
|
|
2181
|
+
if (this.timer) {
|
|
2182
|
+
clearTimeout(this.timer);
|
|
2183
|
+
this.timer = void 0;
|
|
1910
2184
|
}
|
|
1911
|
-
|
|
2185
|
+
const drain = async () => {
|
|
2186
|
+
await this.flush();
|
|
2187
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
2188
|
+
})));
|
|
2189
|
+
};
|
|
2190
|
+
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
2191
|
+
if (!settled && this.debug) {
|
|
2192
|
+
console.warn("[raindrop] direct: shutdown deadline exceeded; abandoning in-flight spans");
|
|
2193
|
+
}
|
|
2194
|
+
} finally {
|
|
2195
|
+
this.shutdownDeadlineAt = void 0;
|
|
1912
2196
|
}
|
|
1913
2197
|
}
|
|
1914
|
-
|
|
1915
|
-
}
|
|
1916
|
-
async function postJson2(url, body, headers, opts) {
|
|
1917
|
-
var _a;
|
|
1918
|
-
const opName = `POST ${redactUrlForLog(url)}`;
|
|
1919
|
-
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1920
|
-
await withRetry2(
|
|
1921
|
-
async () => {
|
|
1922
|
-
const resp = await runWithTracingSuppressed(
|
|
1923
|
-
() => fetch(url, {
|
|
1924
|
-
method: "POST",
|
|
1925
|
-
headers: {
|
|
1926
|
-
"Content-Type": "application/json",
|
|
1927
|
-
...headers
|
|
1928
|
-
},
|
|
1929
|
-
body: JSON.stringify(body),
|
|
1930
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
1931
|
-
})
|
|
1932
|
-
);
|
|
1933
|
-
if (!resp.ok) {
|
|
1934
|
-
const text = await resp.text().catch(() => "");
|
|
1935
|
-
const err = new Error(
|
|
1936
|
-
`HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
|
|
1937
|
-
);
|
|
1938
|
-
const retryAfterMs = parseRetryAfter2(resp.headers);
|
|
1939
|
-
if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
|
|
1940
|
-
throw err;
|
|
1941
|
-
}
|
|
1942
|
-
},
|
|
1943
|
-
opName,
|
|
1944
|
-
opts
|
|
1945
|
-
);
|
|
1946
|
-
}
|
|
2198
|
+
};
|
|
1947
2199
|
|
|
1948
|
-
// src/tracing/
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2200
|
+
// src/tracing/otel-core/index.ts
|
|
2201
|
+
import {
|
|
2202
|
+
DiagConsoleLogger,
|
|
2203
|
+
DiagLogLevel,
|
|
2204
|
+
context as context2,
|
|
2205
|
+
diag,
|
|
2206
|
+
trace as trace2
|
|
2207
|
+
} from "@opentelemetry/api";
|
|
2208
|
+
import { suppressTracing } from "@opentelemetry/core";
|
|
2209
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
2210
|
+
import { registerInstrumentations } from "@opentelemetry/instrumentation";
|
|
2211
|
+
import * as resourceModule from "@opentelemetry/resources";
|
|
2212
|
+
import {
|
|
2213
|
+
BatchSpanProcessor,
|
|
2214
|
+
SimpleSpanProcessor
|
|
2215
|
+
} from "@opentelemetry/sdk-trace-base";
|
|
2216
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
2217
|
+
import {
|
|
2218
|
+
CONTEXT_KEY_ALLOW_TRACE_CONTENT,
|
|
2219
|
+
SpanAttributes,
|
|
2220
|
+
TraceloopSpanKindValues
|
|
2221
|
+
} from "@traceloop/ai-semantic-conventions";
|
|
2222
|
+
var ALL_INSTRUMENTATION_LIBRARIES = "all";
|
|
2223
|
+
var TRACER_NAME = "@traceloop/node-server-sdk";
|
|
2224
|
+
var WORKFLOW_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.workflowName");
|
|
2225
|
+
var ENTITY_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.entityName");
|
|
2226
|
+
var ASSOCIATION_PROPERTIES_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.associationProperties");
|
|
2227
|
+
var INSTRUMENTATION_LIBRARIES = [
|
|
2228
|
+
"ai",
|
|
2229
|
+
"@traceloop/node-server-sdk",
|
|
2230
|
+
"@traceloop/instrumentation-openai",
|
|
2231
|
+
"@traceloop/instrumentation-langchain",
|
|
2232
|
+
"@traceloop/instrumentation-chroma",
|
|
2233
|
+
"@traceloop/instrumentation-chromadb",
|
|
2234
|
+
"@traceloop/instrumentation-anthropic",
|
|
2235
|
+
"@traceloop/instrumentation-llamaindex",
|
|
2236
|
+
"@traceloop/instrumentation-vertexai",
|
|
2237
|
+
"@traceloop/instrumentation-bedrock",
|
|
2238
|
+
"@traceloop/instrumentation-cohere",
|
|
2239
|
+
"@traceloop/instrumentation-pinecone",
|
|
2240
|
+
"@traceloop/instrumentation-qdrant",
|
|
2241
|
+
"@traceloop/instrumentation-together",
|
|
2242
|
+
TRACER_NAME,
|
|
2243
|
+
"traceloop.tracer"
|
|
2244
|
+
];
|
|
2245
|
+
var AI_GENERATE_TEXT = "ai.generateText.doGenerate";
|
|
2246
|
+
var AI_STREAM_TEXT = "ai.streamText.doStream";
|
|
2247
|
+
var AI_RESPONSE_TEXT = "ai.response.text";
|
|
2248
|
+
var AI_PROMPT_MESSAGES = "ai.prompt.messages";
|
|
2249
|
+
var AI_PROMPT_TOKENS = "ai.usage.promptTokens";
|
|
2250
|
+
var AI_COMPLETION_TOKENS = "ai.usage.completionTokens";
|
|
2251
|
+
var AI_MODEL_PROVIDER = "ai.model.provider";
|
|
2252
|
+
var STATE_KEY3 = /* @__PURE__ */ Symbol.for("raindrop.otelCore.state");
|
|
2253
|
+
function getState2() {
|
|
2254
|
+
var _a;
|
|
2255
|
+
const holder = globalThis;
|
|
2256
|
+
(_a = holder[STATE_KEY3]) != null ? _a : holder[STATE_KEY3] = {};
|
|
2257
|
+
return holder[STATE_KEY3];
|
|
1991
2258
|
}
|
|
1992
|
-
function
|
|
1993
|
-
const
|
|
1994
|
-
if (
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2259
|
+
function parseHeaders(value) {
|
|
2260
|
+
const headers = {};
|
|
2261
|
+
if (!value) return headers;
|
|
2262
|
+
for (const pair of value.split(",")) {
|
|
2263
|
+
const separator = pair.indexOf("=");
|
|
2264
|
+
if (separator <= 0) continue;
|
|
2265
|
+
try {
|
|
2266
|
+
const key = decodeURIComponent(pair.slice(0, separator).trim());
|
|
2267
|
+
const val = decodeURIComponent(pair.slice(separator + 1).trim());
|
|
2268
|
+
if (key && val) headers[key] = val;
|
|
2269
|
+
} catch (e) {
|
|
2003
2270
|
}
|
|
2004
|
-
return hex;
|
|
2005
2271
|
}
|
|
2006
|
-
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
// src/tracing/direct/otlp.ts
|
|
2010
|
-
var libraryVersion = package_default.version;
|
|
2011
|
-
var SERVICE_NAME = "raindrop-ai";
|
|
2012
|
-
function attrString2(key, value) {
|
|
2013
|
-
if (value === void 0) return void 0;
|
|
2014
|
-
return { key, value: { stringValue: value } };
|
|
2272
|
+
return headers;
|
|
2015
2273
|
}
|
|
2016
|
-
function
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2274
|
+
function safeStringify(value) {
|
|
2275
|
+
try {
|
|
2276
|
+
const result = JSON.stringify(value);
|
|
2277
|
+
return result === void 0 ? String(value) : result;
|
|
2278
|
+
} catch (e) {
|
|
2279
|
+
return "[unserializable]";
|
|
2280
|
+
}
|
|
2020
2281
|
}
|
|
2021
|
-
function
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
startTimeUnixNano: args.startTimeUnixNano,
|
|
2028
|
-
endTimeUnixNano: args.endTimeUnixNano
|
|
2029
|
-
};
|
|
2030
|
-
if (args.ids.parentSpanIdB64) span.parentSpanId = args.ids.parentSpanIdB64;
|
|
2031
|
-
if (attrs.length) span.attributes = attrs;
|
|
2032
|
-
if (args.status) span.status = args.status;
|
|
2033
|
-
return span;
|
|
2282
|
+
function createResource(attributes) {
|
|
2283
|
+
if ("resourceFromAttributes" in resourceModule) {
|
|
2284
|
+
const factory = resourceModule.resourceFromAttributes;
|
|
2285
|
+
if (typeof factory === "function") return factory(attributes);
|
|
2286
|
+
}
|
|
2287
|
+
return new resourceModule.Resource(attributes);
|
|
2034
2288
|
}
|
|
2035
|
-
function
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
{
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2289
|
+
function detectRuntimeResource() {
|
|
2290
|
+
try {
|
|
2291
|
+
if ("detectResourcesSync" in resourceModule && typeof resourceModule.detectResourcesSync === "function" && "envDetectorSync" in resourceModule) {
|
|
2292
|
+
return resourceModule.detectResourcesSync({
|
|
2293
|
+
detectors: [
|
|
2294
|
+
resourceModule.envDetectorSync,
|
|
2295
|
+
resourceModule.processDetectorSync,
|
|
2296
|
+
resourceModule.hostDetectorSync
|
|
2297
|
+
]
|
|
2298
|
+
});
|
|
2299
|
+
}
|
|
2300
|
+
if ("detectResources" in resourceModule && typeof resourceModule.detectResources === "function" && "envDetector" in resourceModule) {
|
|
2301
|
+
const detected = resourceModule.detectResources({
|
|
2302
|
+
detectors: [
|
|
2303
|
+
resourceModule.envDetector,
|
|
2304
|
+
resourceModule.processDetector,
|
|
2305
|
+
resourceModule.hostDetector
|
|
2047
2306
|
]
|
|
2307
|
+
});
|
|
2308
|
+
if (!(detected instanceof Promise)) {
|
|
2309
|
+
return detected;
|
|
2048
2310
|
}
|
|
2049
|
-
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
// src/tracing/direct/context.ts
|
|
2054
|
-
import { context as context2, isValidSpanId, isValidTraceId, trace as trace2 } from "@opentelemetry/api";
|
|
2055
|
-
var INVALID_TRACE_ID = "00000000000000000000000000000000";
|
|
2056
|
-
var INVALID_SPAN_ID = "0000000000000000";
|
|
2057
|
-
function hexToBase64(hex) {
|
|
2058
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
2059
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
2060
|
-
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
2311
|
+
}
|
|
2312
|
+
} catch (e) {
|
|
2061
2313
|
}
|
|
2062
|
-
return
|
|
2314
|
+
return void 0;
|
|
2063
2315
|
}
|
|
2064
|
-
function
|
|
2065
|
-
|
|
2066
|
-
|
|
2316
|
+
function logLevel(level) {
|
|
2317
|
+
switch (level) {
|
|
2318
|
+
case "debug":
|
|
2319
|
+
return DiagLogLevel.DEBUG;
|
|
2320
|
+
case "info":
|
|
2321
|
+
return DiagLogLevel.INFO;
|
|
2322
|
+
case "warn":
|
|
2323
|
+
return DiagLogLevel.WARN;
|
|
2324
|
+
default:
|
|
2325
|
+
return DiagLogLevel.ERROR;
|
|
2067
2326
|
}
|
|
2068
|
-
return {
|
|
2069
|
-
traceIdB64: hexToBase64(traceId),
|
|
2070
|
-
parentSpanIdB64: hexToBase64(parentSpanId)
|
|
2071
|
-
};
|
|
2072
2327
|
}
|
|
2073
|
-
function
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
const traceIdHex = spanContext.traceId;
|
|
2078
|
-
const spanIdHex = spanContext.spanId;
|
|
2079
|
-
if (traceIdHex === INVALID_TRACE_ID) return {};
|
|
2080
|
-
return {
|
|
2081
|
-
traceIdB64: hexToBase64(traceIdHex),
|
|
2082
|
-
parentSpanIdB64: spanIdHex !== INVALID_SPAN_ID ? hexToBase64(spanIdHex) : void 0
|
|
2328
|
+
function transformAiSdkSpan(span) {
|
|
2329
|
+
const names = {
|
|
2330
|
+
[AI_GENERATE_TEXT]: "ai.generateText.generate",
|
|
2331
|
+
[AI_STREAM_TEXT]: "ai.streamText.stream"
|
|
2083
2332
|
};
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
}
|
|
2090
|
-
var DirectTraceShipper = class {
|
|
2091
|
-
constructor(opts) {
|
|
2092
|
-
this.queue = [];
|
|
2093
|
-
this.inFlight = /* @__PURE__ */ new Set();
|
|
2094
|
-
/**
|
|
2095
|
-
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
2096
|
-
* drain window (stragglers, or flush work the deadline abandoned
|
|
2097
|
-
* mid-drain) run as a single short attempt instead of regaining the full
|
|
2098
|
-
* retry schedule.
|
|
2099
|
-
*/
|
|
2100
|
-
this.hasShutdown = false;
|
|
2101
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2102
|
-
this.writeKey = opts.writeKey;
|
|
2103
|
-
this.baseUrl = (_a = formatEndpoint2(opts.endpoint)) != null ? _a : "https://api.raindrop.ai/v1/";
|
|
2104
|
-
this.enabled = (_b = opts.enabled) != null ? _b : true;
|
|
2105
|
-
this.cloudEnabled = (_c = opts.cloudEnabled) != null ? _c : true;
|
|
2106
|
-
this.debug = opts.debug;
|
|
2107
|
-
this.projectId = opts.projectId;
|
|
2108
|
-
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
2109
|
-
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
2110
|
-
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
2111
|
-
const resolved = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl);
|
|
2112
|
-
if (resolved && resolved !== this.baseUrl) {
|
|
2113
|
-
this.localDebuggerUrl = resolved;
|
|
2333
|
+
if (!(span.name in names)) return span;
|
|
2334
|
+
const attributes = span.attributes;
|
|
2335
|
+
if (AI_RESPONSE_TEXT in attributes) {
|
|
2336
|
+
const response = attributes[AI_RESPONSE_TEXT];
|
|
2337
|
+
if (typeof response === "string") {
|
|
2338
|
+
attributes[`${SpanAttributes.LLM_COMPLETIONS}.0.content`] = response;
|
|
2114
2339
|
}
|
|
2340
|
+
attributes[`${SpanAttributes.LLM_COMPLETIONS}.0.role`] = "assistant";
|
|
2341
|
+
delete attributes[AI_RESPONSE_TEXT];
|
|
2115
2342
|
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
traceIdB64 = activeCtx.traceIdB64;
|
|
2130
|
-
parentSpanIdB64 = activeCtx.parentSpanIdB64;
|
|
2131
|
-
}
|
|
2132
|
-
const spanIdB64 = (_a = params.spanId) != null ? _a : base64Encode2(randomBytes2(8));
|
|
2133
|
-
if (!traceIdB64) {
|
|
2134
|
-
traceIdB64 = base64Encode2(randomBytes2(16));
|
|
2135
|
-
}
|
|
2136
|
-
const startTimeUnixNano = String(params.startTimeMs * 1e6);
|
|
2137
|
-
const endTimeUnixNano = String(params.endTimeMs * 1e6);
|
|
2138
|
-
const attributes = [
|
|
2139
|
-
// Required: passes hasAIOperation() filter in backend (parseSpan.ts)
|
|
2140
|
-
attrString2("traceloop.span.kind", (_b = params.spanKind) != null ? _b : "tool"),
|
|
2141
|
-
// Parsed by backend for input/output payloads
|
|
2142
|
-
attrString2("traceloop.entity.input", params.input),
|
|
2143
|
-
attrString2("traceloop.entity.output", params.output),
|
|
2144
|
-
// Duration tracking
|
|
2145
|
-
attrInt2("traceloop.entity.duration_ms", params.durationMs),
|
|
2146
|
-
// Per-span project routing: the ingest boundary routes on this attribute
|
|
2147
|
-
// (org-validated) and falls back to the request's project header. Direct
|
|
2148
|
-
// spans ship on this instance's own key, so no cross-key auth hint.
|
|
2149
|
-
attrString2(PROJECT_ID_SPAN_ATTRIBUTE, this.projectId)
|
|
2150
|
-
];
|
|
2151
|
-
for (const [key, value] of Object.entries(params.properties)) {
|
|
2152
|
-
if (value === void 0) {
|
|
2153
|
-
continue;
|
|
2343
|
+
if (AI_PROMPT_MESSAGES in attributes) {
|
|
2344
|
+
try {
|
|
2345
|
+
const parsed = JSON.parse(String(attributes[AI_PROMPT_MESSAGES]));
|
|
2346
|
+
if (Array.isArray(parsed)) {
|
|
2347
|
+
parsed.forEach((message, index) => {
|
|
2348
|
+
if (!message || typeof message !== "object") return;
|
|
2349
|
+
const content = "content" in message ? message.content : void 0;
|
|
2350
|
+
const role = "role" in message ? message.role : void 0;
|
|
2351
|
+
attributes[`${SpanAttributes.LLM_PROMPTS}.${index}.content`] = typeof content === "string" ? content : safeStringify(content);
|
|
2352
|
+
if (typeof role === "string") {
|
|
2353
|
+
attributes[`${SpanAttributes.LLM_PROMPTS}.${index}.role`] = role;
|
|
2354
|
+
}
|
|
2355
|
+
});
|
|
2154
2356
|
}
|
|
2155
|
-
attributes
|
|
2156
|
-
|
|
2157
|
-
);
|
|
2158
|
-
}
|
|
2159
|
-
const spanIdentity = { spanIdB64 };
|
|
2160
|
-
claimSpanForFrames(spanIdentity);
|
|
2161
|
-
for (const [key, value] of Object.entries({
|
|
2162
|
-
...currentSpanAttributes(),
|
|
2163
|
-
...params.attributes
|
|
2164
|
-
})) {
|
|
2165
|
-
attributes.push(attrString2(key, value));
|
|
2166
|
-
}
|
|
2167
|
-
attributes.push(...(_c = params.otlpAttributes) != null ? _c : []);
|
|
2168
|
-
let status;
|
|
2169
|
-
if (params.error) {
|
|
2170
|
-
status = { code: 2, message: params.error };
|
|
2171
|
-
markErrorSpanSeen(spanIdentity);
|
|
2172
|
-
} else {
|
|
2173
|
-
status = {
|
|
2174
|
-
code: 1
|
|
2175
|
-
/* STATUS_CODE_OK */
|
|
2176
|
-
};
|
|
2357
|
+
delete attributes[AI_PROMPT_MESSAGES];
|
|
2358
|
+
} catch (e) {
|
|
2177
2359
|
}
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2360
|
+
}
|
|
2361
|
+
if (AI_PROMPT_TOKENS in attributes) {
|
|
2362
|
+
attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] = Number(attributes[AI_PROMPT_TOKENS]);
|
|
2363
|
+
delete attributes[AI_PROMPT_TOKENS];
|
|
2364
|
+
}
|
|
2365
|
+
if (AI_COMPLETION_TOKENS in attributes) {
|
|
2366
|
+
attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] = Number(
|
|
2367
|
+
attributes[AI_COMPLETION_TOKENS]
|
|
2368
|
+
);
|
|
2369
|
+
delete attributes[AI_COMPLETION_TOKENS];
|
|
2370
|
+
}
|
|
2371
|
+
const prompt = attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS];
|
|
2372
|
+
const completion = attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS];
|
|
2373
|
+
if (prompt !== void 0 && completion !== void 0) {
|
|
2374
|
+
attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] = Number(prompt) + Number(completion);
|
|
2375
|
+
}
|
|
2376
|
+
if (AI_MODEL_PROVIDER in attributes) {
|
|
2377
|
+
const vendor = String(attributes[AI_MODEL_PROVIDER]);
|
|
2378
|
+
attributes[SpanAttributes.LLM_SYSTEM] = vendor.startsWith("openai") ? "OpenAI" : vendor;
|
|
2379
|
+
delete attributes[AI_MODEL_PROVIDER];
|
|
2380
|
+
}
|
|
2381
|
+
Object.defineProperty(span, "name", {
|
|
2382
|
+
configurable: true,
|
|
2383
|
+
value: names[span.name],
|
|
2384
|
+
writable: true
|
|
2385
|
+
});
|
|
2386
|
+
return span;
|
|
2387
|
+
}
|
|
2388
|
+
function scopeName(span) {
|
|
2389
|
+
var _a;
|
|
2390
|
+
if ("instrumentationScope" in span) {
|
|
2391
|
+
const scope = span.instrumentationScope;
|
|
2392
|
+
if (scope && typeof scope === "object" && "name" in scope && typeof scope.name === "string") {
|
|
2393
|
+
return scope.name;
|
|
2197
2394
|
}
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2395
|
+
}
|
|
2396
|
+
return (_a = span.instrumentationLibrary) == null ? void 0 : _a.name;
|
|
2397
|
+
}
|
|
2398
|
+
function contentCaptureDisabled(options) {
|
|
2399
|
+
return options.traceContent === false || (process.env.TRACELOOP_TRACE_CONTENT || "true").toLowerCase() === "false";
|
|
2400
|
+
}
|
|
2401
|
+
function shouldSendTraceContent() {
|
|
2402
|
+
var _a;
|
|
2403
|
+
const contextual = context2.active().getValue(CONTEXT_KEY_ALLOW_TRACE_CONTENT);
|
|
2404
|
+
if (typeof contextual === "boolean") return contextual;
|
|
2405
|
+
if (((_a = getState2().configuration) == null ? void 0 : _a.traceContent) === false) return false;
|
|
2406
|
+
return (process.env.TRACELOOP_TRACE_CONTENT || "true").toLowerCase() !== "false";
|
|
2407
|
+
}
|
|
2408
|
+
function enrichStart(span) {
|
|
2409
|
+
const active = context2.active();
|
|
2410
|
+
const workflow = active.getValue(WORKFLOW_NAME_KEY);
|
|
2411
|
+
if (typeof workflow === "string")
|
|
2412
|
+
span.setAttribute(SpanAttributes.TRACELOOP_WORKFLOW_NAME, workflow);
|
|
2413
|
+
const entity = active.getValue(ENTITY_NAME_KEY);
|
|
2414
|
+
if (typeof entity === "string") span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_PATH, entity);
|
|
2415
|
+
const properties = active.getValue(ASSOCIATION_PROPERTIES_KEY);
|
|
2416
|
+
if (properties && typeof properties === "object") {
|
|
2417
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
2418
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
2419
|
+
span.setAttribute(`${SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.${key}`, value);
|
|
2420
|
+
}
|
|
2201
2421
|
}
|
|
2202
2422
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2423
|
+
}
|
|
2424
|
+
function createSpanProcessor(options) {
|
|
2425
|
+
var _a, _b;
|
|
2426
|
+
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
2427
|
+
const apiKey = options.apiKey || process.env.TRACELOOP_API_KEY;
|
|
2428
|
+
const resolvedHeaders = (_a = options.headers) != null ? _a : process.env.TRACELOOP_HEADERS ? parseHeaders(process.env.TRACELOOP_HEADERS) : { Authorization: `Bearer ${apiKey}` };
|
|
2429
|
+
const baseExporter = (_b = options.exporter) != null ? _b : new OTLPTraceExporter({ url: `${baseUrl}/v1/traces`, headers: resolvedHeaders });
|
|
2430
|
+
const exporter = options.routeReplayTraces ? new ReplayRoutingSpanExporter(baseExporter) : baseExporter;
|
|
2431
|
+
const processor = options.disableBatch ? new SimpleSpanProcessor(exporter) : new BatchSpanProcessor(exporter);
|
|
2432
|
+
const originalOnStart = processor.onStart.bind(processor);
|
|
2433
|
+
const originalOnEnd = processor.onEnd.bind(processor);
|
|
2434
|
+
processor.onStart = (span, parentContext) => {
|
|
2435
|
+
try {
|
|
2436
|
+
enrichStart(span);
|
|
2437
|
+
originalOnStart(span, parentContext);
|
|
2438
|
+
} catch (e) {
|
|
2213
2439
|
}
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2440
|
+
};
|
|
2441
|
+
processor.onEnd = (span) => {
|
|
2442
|
+
var _a2;
|
|
2443
|
+
let outgoing = span;
|
|
2444
|
+
try {
|
|
2445
|
+
const allowed = options.allowedInstrumentationLibraries;
|
|
2446
|
+
if (allowed !== ALL_INSTRUMENTATION_LIBRARIES && ![...INSTRUMENTATION_LIBRARIES, ...allowed != null ? allowed : []].includes((_a2 = scopeName(span)) != null ? _a2 : "")) {
|
|
2447
|
+
return;
|
|
2448
|
+
}
|
|
2449
|
+
outgoing = transformAiSdkSpan(span);
|
|
2450
|
+
if (outgoing !== span) copyReplayTraceDestination(span, outgoing);
|
|
2451
|
+
} catch (e) {
|
|
2219
2452
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
void this.flush().catch(() => {
|
|
2224
|
-
});
|
|
2225
|
-
}, this.flushIntervalMs);
|
|
2453
|
+
try {
|
|
2454
|
+
originalOnEnd(outgoing);
|
|
2455
|
+
} catch (e) {
|
|
2226
2456
|
}
|
|
2227
|
-
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2457
|
+
};
|
|
2458
|
+
return processor;
|
|
2459
|
+
}
|
|
2460
|
+
function initialize(options = {}) {
|
|
2461
|
+
var _a;
|
|
2462
|
+
const state2 = getState2();
|
|
2463
|
+
if (state2.configuration) return;
|
|
2464
|
+
state2.configuration = Object.freeze({ ...options });
|
|
2465
|
+
if (options.logLevel) diag.setLogger(new DiagConsoleLogger(), logLevel(options.logLevel));
|
|
2466
|
+
if (options.tracingEnabled === false) return;
|
|
2467
|
+
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
2468
|
+
state2.defaultProcessor = createSpanProcessor({
|
|
2469
|
+
...options,
|
|
2470
|
+
baseUrl,
|
|
2471
|
+
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
2472
|
+
});
|
|
2473
|
+
const serviceResource = createResource({
|
|
2474
|
+
"service.name": options.appName || process.env.npm_package_name || "unknown_service"
|
|
2475
|
+
});
|
|
2476
|
+
const detectedResource = detectRuntimeResource();
|
|
2477
|
+
state2.provider = new NodeTracerProvider({
|
|
2478
|
+
// Detected attributes win over the configured resource, matching
|
|
2479
|
+
// sdk-node's `this._resource.merge(detectResourcesSync(...))` so
|
|
2480
|
+
// OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES can still override appName.
|
|
2481
|
+
resource: detectedResource ? serviceResource.merge(detectedResource) : serviceResource,
|
|
2482
|
+
spanProcessors: [state2.defaultProcessor, ...options.processor ? [options.processor] : []]
|
|
2483
|
+
});
|
|
2484
|
+
state2.provider.register({
|
|
2485
|
+
contextManager: options.contextManager,
|
|
2486
|
+
propagator: options.propagator
|
|
2487
|
+
});
|
|
2488
|
+
const instrumentations = (_a = options.instrumentations) != null ? _a : [];
|
|
2489
|
+
if (contentCaptureDisabled(options)) {
|
|
2490
|
+
for (const instrumentation of instrumentations) {
|
|
2491
|
+
try {
|
|
2492
|
+
const config = {
|
|
2493
|
+
...instrumentation.getConfig(),
|
|
2494
|
+
traceContent: false
|
|
2495
|
+
};
|
|
2496
|
+
instrumentation.setConfig(config);
|
|
2497
|
+
} catch (e) {
|
|
2498
|
+
}
|
|
2233
2499
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2500
|
+
}
|
|
2501
|
+
registerInstrumentations({ instrumentations });
|
|
2502
|
+
}
|
|
2503
|
+
async function forceFlush() {
|
|
2504
|
+
var _a, _b;
|
|
2505
|
+
const state2 = getState2();
|
|
2506
|
+
try {
|
|
2507
|
+
await ((_a = state2.provider) == null ? void 0 : _a.forceFlush());
|
|
2508
|
+
await ((_b = state2.defaultProcessor) == null ? void 0 : _b.forceFlush());
|
|
2509
|
+
} catch (e) {
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
function withEntity(type, config, fn, args) {
|
|
2513
|
+
let entityContext = context2.active();
|
|
2514
|
+
if (type === TraceloopSpanKindValues.WORKFLOW) {
|
|
2515
|
+
entityContext = entityContext.setValue(WORKFLOW_NAME_KEY, config.name);
|
|
2516
|
+
}
|
|
2517
|
+
const parentPath = entityContext.getValue(ENTITY_NAME_KEY);
|
|
2518
|
+
if (type === TraceloopSpanKindValues.TASK || type === TraceloopSpanKindValues.TOOL) {
|
|
2519
|
+
entityContext = entityContext.setValue(
|
|
2520
|
+
ENTITY_NAME_KEY,
|
|
2521
|
+
`${typeof parentPath === "string" ? `${parentPath}.` : ""}${config.name}`
|
|
2522
|
+
);
|
|
2523
|
+
}
|
|
2524
|
+
if (config.traceContent !== void 0) {
|
|
2525
|
+
entityContext = entityContext.setValue(CONTEXT_KEY_ALLOW_TRACE_CONTENT, config.traceContent);
|
|
2526
|
+
}
|
|
2527
|
+
if (config.associationProperties) {
|
|
2528
|
+
entityContext = entityContext.setValue(
|
|
2529
|
+
ASSOCIATION_PROPERTIES_KEY,
|
|
2530
|
+
config.associationProperties
|
|
2531
|
+
);
|
|
2532
|
+
}
|
|
2533
|
+
if (config.suppressTracing) {
|
|
2534
|
+
entityContext = suppressTracing(entityContext);
|
|
2535
|
+
}
|
|
2536
|
+
let callbackStarted = false;
|
|
2537
|
+
const run = (span) => {
|
|
2538
|
+
var _a;
|
|
2539
|
+
try {
|
|
2540
|
+
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_NAME, config.name);
|
|
2541
|
+
span.setAttribute(
|
|
2542
|
+
SpanAttributes.TRACELOOP_ENTITY_PATH,
|
|
2543
|
+
typeof parentPath === "string" ? parentPath : ""
|
|
2544
|
+
);
|
|
2545
|
+
span.setAttribute(SpanAttributes.TRACELOOP_SPAN_KIND, type);
|
|
2546
|
+
if (type === TraceloopSpanKindValues.WORKFLOW) {
|
|
2547
|
+
span.setAttribute(SpanAttributes.TRACELOOP_WORKFLOW_NAME, config.name);
|
|
2239
2548
|
}
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2549
|
+
if (config.version !== void 0)
|
|
2550
|
+
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_VERSION, config.version);
|
|
2551
|
+
const input = (_a = config.inputParameters) != null ? _a : args;
|
|
2552
|
+
if (shouldSendTraceContent()) {
|
|
2553
|
+
span.setAttribute(
|
|
2554
|
+
SpanAttributes.TRACELOOP_ENTITY_INPUT,
|
|
2555
|
+
safeStringify(
|
|
2556
|
+
input.length === 1 && input[0] !== null && typeof input[0] === "object" && !(input[0] instanceof Map) ? { args: [], kwargs: input[0] } : { args: input, kwargs: {} }
|
|
2246
2557
|
)
|
|
2247
2558
|
);
|
|
2248
|
-
continue;
|
|
2249
2559
|
}
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
);
|
|
2258
|
-
this.inFlight.add(p);
|
|
2560
|
+
} catch (e) {
|
|
2561
|
+
}
|
|
2562
|
+
let result;
|
|
2563
|
+
try {
|
|
2564
|
+
callbackStarted = true;
|
|
2565
|
+
result = fn(...args);
|
|
2566
|
+
} catch (error) {
|
|
2259
2567
|
try {
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
if (this.debug) console.log(`[raindrop] direct: sent ${batch.length} spans`);
|
|
2263
|
-
} catch (err) {
|
|
2264
|
-
if (this.debug) {
|
|
2265
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2266
|
-
console.warn(`[raindrop] direct: failed to send spans (dropping): ${msg}`);
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
} finally {
|
|
2270
|
-
this.inFlight.delete(p);
|
|
2568
|
+
span.end();
|
|
2569
|
+
} catch (e) {
|
|
2271
2570
|
}
|
|
2571
|
+
throw error;
|
|
2272
2572
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
return { maxAttempts: 1, debug: this.debug, timeoutMs: POST_SHUTDOWN_TIMEOUT_MS };
|
|
2573
|
+
if (result instanceof Promise) {
|
|
2574
|
+
return result.then(
|
|
2575
|
+
(value) => {
|
|
2576
|
+
try {
|
|
2577
|
+
if (shouldSendTraceContent())
|
|
2578
|
+
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(value));
|
|
2579
|
+
span.end();
|
|
2580
|
+
} catch (e) {
|
|
2581
|
+
}
|
|
2582
|
+
return value;
|
|
2583
|
+
},
|
|
2584
|
+
(error) => {
|
|
2585
|
+
try {
|
|
2586
|
+
span.end();
|
|
2587
|
+
} catch (e) {
|
|
2588
|
+
}
|
|
2589
|
+
throw error;
|
|
2590
|
+
}
|
|
2591
|
+
);
|
|
2293
2592
|
}
|
|
2294
|
-
return { maxAttempts: 3, debug: this.debug };
|
|
2295
|
-
}
|
|
2296
|
-
async shutdown() {
|
|
2297
|
-
this.hasShutdown = true;
|
|
2298
|
-
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
2299
2593
|
try {
|
|
2300
|
-
if (
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
const drain = async () => {
|
|
2305
|
-
await this.flush();
|
|
2306
|
-
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
2307
|
-
})));
|
|
2308
|
-
};
|
|
2309
|
-
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
2310
|
-
if (!settled && this.debug) {
|
|
2311
|
-
console.warn("[raindrop] direct: shutdown deadline exceeded; abandoning in-flight spans");
|
|
2312
|
-
}
|
|
2313
|
-
} finally {
|
|
2314
|
-
this.shutdownDeadlineAt = void 0;
|
|
2594
|
+
if (shouldSendTraceContent())
|
|
2595
|
+
span.setAttribute(SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(result));
|
|
2596
|
+
span.end();
|
|
2597
|
+
} catch (e) {
|
|
2315
2598
|
}
|
|
2599
|
+
return result;
|
|
2600
|
+
};
|
|
2601
|
+
try {
|
|
2602
|
+
const tracer = trace2.getTracer(TRACER_NAME);
|
|
2603
|
+
return context2.with(
|
|
2604
|
+
entityContext,
|
|
2605
|
+
() => tracer.startActiveSpan(`${config.name}.${type}`, {}, entityContext, run)
|
|
2606
|
+
);
|
|
2607
|
+
} catch (error) {
|
|
2608
|
+
if (callbackStarted) throw error;
|
|
2609
|
+
return fn(...args);
|
|
2316
2610
|
}
|
|
2317
|
-
}
|
|
2611
|
+
}
|
|
2612
|
+
function withTask(config, fn, ...args) {
|
|
2613
|
+
return withEntity(TraceloopSpanKindValues.TASK, config, fn, args);
|
|
2614
|
+
}
|
|
2615
|
+
function withTool(config, fn, ...args) {
|
|
2616
|
+
return withEntity(TraceloopSpanKindValues.TOOL, config, fn, args);
|
|
2617
|
+
}
|
|
2318
2618
|
|
|
2319
2619
|
// src/tracing/exit-flush.ts
|
|
2320
|
-
var
|
|
2620
|
+
var STATE_KEY4 = /* @__PURE__ */ Symbol.for("raindrop.tracing.exitFlushState");
|
|
2321
2621
|
function getState3() {
|
|
2322
2622
|
const holder = globalThis;
|
|
2323
|
-
let
|
|
2324
|
-
if (!
|
|
2325
|
-
|
|
2623
|
+
let state2 = holder[STATE_KEY4];
|
|
2624
|
+
if (!state2) {
|
|
2625
|
+
state2 = {
|
|
2326
2626
|
clientFlushers: /* @__PURE__ */ new Set(),
|
|
2327
2627
|
pipelineFlushNeeded: false,
|
|
2328
2628
|
handlerRegistered: false
|
|
2329
2629
|
};
|
|
2330
|
-
holder[
|
|
2630
|
+
holder[STATE_KEY4] = state2;
|
|
2331
2631
|
}
|
|
2332
|
-
return
|
|
2632
|
+
return state2;
|
|
2333
2633
|
}
|
|
2334
|
-
function ensureExitHandler(
|
|
2335
|
-
if (
|
|
2634
|
+
function ensureExitHandler(state2) {
|
|
2635
|
+
if (state2.handlerRegistered) return;
|
|
2336
2636
|
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
2337
|
-
|
|
2637
|
+
state2.handlerRegistered = true;
|
|
2338
2638
|
process.once("beforeExit", () => {
|
|
2339
2639
|
void flushAll();
|
|
2340
2640
|
});
|
|
2341
2641
|
}
|
|
2342
2642
|
function registerClientFlusher(flush) {
|
|
2343
|
-
const
|
|
2344
|
-
|
|
2345
|
-
ensureExitHandler(
|
|
2643
|
+
const state2 = getState3();
|
|
2644
|
+
state2.clientFlushers.add(flush);
|
|
2645
|
+
ensureExitHandler(state2);
|
|
2346
2646
|
return () => {
|
|
2347
|
-
|
|
2647
|
+
state2.clientFlushers.delete(flush);
|
|
2348
2648
|
};
|
|
2349
2649
|
}
|
|
2350
2650
|
function markPipelineForExitFlush() {
|
|
2351
|
-
const
|
|
2352
|
-
|
|
2353
|
-
ensureExitHandler(
|
|
2651
|
+
const state2 = getState3();
|
|
2652
|
+
state2.pipelineFlushNeeded = true;
|
|
2653
|
+
ensureExitHandler(state2);
|
|
2354
2654
|
}
|
|
2355
2655
|
async function flushAll() {
|
|
2356
|
-
const
|
|
2656
|
+
const state2 = getState3();
|
|
2357
2657
|
const tasks = [];
|
|
2358
|
-
for (const flush of
|
|
2658
|
+
for (const flush of state2.clientFlushers) {
|
|
2359
2659
|
tasks.push(Promise.resolve().then(flush).catch(() => {
|
|
2360
2660
|
}));
|
|
2361
2661
|
}
|
|
2362
|
-
if (
|
|
2662
|
+
if (state2.pipelineFlushNeeded) {
|
|
2363
2663
|
tasks.push(
|
|
2364
2664
|
Promise.resolve().then(() => forceFlush()).catch(() => {
|
|
2365
2665
|
})
|
|
@@ -3708,6 +4008,14 @@ if (localDebuggerEnabled()) {
|
|
|
3708
4008
|
process.env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = "http/json";
|
|
3709
4009
|
}
|
|
3710
4010
|
}
|
|
4011
|
+
var DropSpanExporter = class {
|
|
4012
|
+
export(_spans, resultCallback) {
|
|
4013
|
+
resultCallback({ code: 0 });
|
|
4014
|
+
}
|
|
4015
|
+
shutdown() {
|
|
4016
|
+
return Promise.resolve();
|
|
4017
|
+
}
|
|
4018
|
+
};
|
|
3711
4019
|
var CompositeSpanProcessor = class {
|
|
3712
4020
|
constructor(requiredProcessors, bestEffortProcessors) {
|
|
3713
4021
|
this.requiredProcessors = requiredProcessors;
|
|
@@ -3839,10 +4147,24 @@ function createLocalDebuggerSpanProcessor(options) {
|
|
|
3839
4147
|
url: `${localDebuggerUrl}traces`,
|
|
3840
4148
|
headers: {}
|
|
3841
4149
|
});
|
|
4150
|
+
if (!options.routeReplayTraces) {
|
|
4151
|
+
const exportLocal = localExporter.export.bind(localExporter);
|
|
4152
|
+
localExporter.export = (spans, callback) => {
|
|
4153
|
+
const localSpans = spans.filter(
|
|
4154
|
+
(span) => {
|
|
4155
|
+
var _a;
|
|
4156
|
+
return ((_a = replayTraceDestinationFor(span)) == null ? void 0 : _a.kind) !== "raindrop";
|
|
4157
|
+
}
|
|
4158
|
+
);
|
|
4159
|
+
if (localSpans.length === 0) callback({ code: 0 });
|
|
4160
|
+
else exportLocal(localSpans, callback);
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
3842
4163
|
try {
|
|
3843
4164
|
return createSpanProcessor({
|
|
3844
4165
|
apiKey: options.writeKey,
|
|
3845
4166
|
baseUrl: localDebuggerUrl,
|
|
4167
|
+
routeReplayTraces: options.routeReplayTraces,
|
|
3846
4168
|
disableBatch: options.disableBatching,
|
|
3847
4169
|
exporter: localExporter,
|
|
3848
4170
|
headers: {},
|
|
@@ -4256,7 +4578,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4256
4578
|
writeKey,
|
|
4257
4579
|
disableBatching,
|
|
4258
4580
|
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES,
|
|
4259
|
-
localDebuggerUrlOpt: localDebuggerUrl
|
|
4581
|
+
localDebuggerUrlOpt: localDebuggerUrl,
|
|
4582
|
+
routeReplayTraces: !cloudEnabledResolved
|
|
4260
4583
|
});
|
|
4261
4584
|
if (!cloudEnabledResolved) {
|
|
4262
4585
|
if (localDebuggerProcessor) {
|
|
@@ -4264,22 +4587,40 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4264
4587
|
baseUrl: apiUrl,
|
|
4265
4588
|
apiKey: writeKey,
|
|
4266
4589
|
...otherOptions,
|
|
4590
|
+
exporter: new DropSpanExporter(),
|
|
4267
4591
|
logLevel: logLevel2,
|
|
4268
4592
|
silenceInitializationMessage: true,
|
|
4269
4593
|
tracingEnabled: tracingEnabled !== false,
|
|
4270
4594
|
disableBatch: disableBatching,
|
|
4271
|
-
processor:
|
|
4595
|
+
processor: new CompositeSpanProcessor(
|
|
4596
|
+
[new RaindropContextSpanProcessor(), localDebuggerProcessor],
|
|
4597
|
+
[]
|
|
4598
|
+
),
|
|
4272
4599
|
instrumentations: createConfiguredInstrumentations(otherOptions)
|
|
4273
4600
|
});
|
|
4274
4601
|
traceloopInitialized = true;
|
|
4275
4602
|
markTraceloopConfiguredWithoutClaim();
|
|
4276
4603
|
} else {
|
|
4604
|
+
const replayOnlyProcessor = createSpanProcessor({
|
|
4605
|
+
exporter: new DropSpanExporter(),
|
|
4606
|
+
routeReplayTraces: true,
|
|
4607
|
+
disableBatch: disableBatching,
|
|
4608
|
+
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
4609
|
+
});
|
|
4277
4610
|
initialize({
|
|
4278
4611
|
baseUrl: apiUrl,
|
|
4279
4612
|
apiKey: writeKey,
|
|
4613
|
+
...otherOptions,
|
|
4614
|
+
exporter: new DropSpanExporter(),
|
|
4280
4615
|
logLevel: logLevel2,
|
|
4281
4616
|
silenceInitializationMessage: true,
|
|
4282
|
-
tracingEnabled: false
|
|
4617
|
+
tracingEnabled: tracingEnabled !== false,
|
|
4618
|
+
disableBatch: disableBatching,
|
|
4619
|
+
processor: new CompositeSpanProcessor(
|
|
4620
|
+
[new RaindropContextSpanProcessor(), replayOnlyProcessor],
|
|
4621
|
+
[]
|
|
4622
|
+
),
|
|
4623
|
+
instrumentations: createConfiguredInstrumentations(otherOptions)
|
|
4283
4624
|
});
|
|
4284
4625
|
traceloopInitialized = true;
|
|
4285
4626
|
markTraceloopConfiguredWithoutClaim();
|
|
@@ -4307,7 +4648,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4307
4648
|
let guardedExporter;
|
|
4308
4649
|
try {
|
|
4309
4650
|
const callerExporter = otherOptions.exporter;
|
|
4310
|
-
|
|
4651
|
+
const guarded = callerExporter ? new GuardedSpanExporter(callerExporter, ownerHint) : buildGuardedExporter(apiUrl, exporterHeaders, ownerHint);
|
|
4652
|
+
guardedExporter = new ReplayRoutingSpanExporter(guarded);
|
|
4311
4653
|
} catch (guardError) {
|
|
4312
4654
|
releasePipelineClaim();
|
|
4313
4655
|
claimedPipeline = false;
|
|
@@ -4558,7 +4900,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4558
4900
|
writeKey,
|
|
4559
4901
|
disableBatching,
|
|
4560
4902
|
allowedInstrumentationLibraries: processorOptions == null ? void 0 : processorOptions.allowedInstrumentationLibraries,
|
|
4561
|
-
localDebuggerUrlOpt: localDebuggerUrl
|
|
4903
|
+
localDebuggerUrlOpt: localDebuggerUrl,
|
|
4904
|
+
routeReplayTraces: true
|
|
4562
4905
|
});
|
|
4563
4906
|
return withV2SpanCompat(
|
|
4564
4907
|
localOnlyProcessor != null ? localOnlyProcessor : {
|
|
@@ -4579,6 +4922,7 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4579
4922
|
apiKey: writeKey,
|
|
4580
4923
|
disableBatch: disableBatching,
|
|
4581
4924
|
...processorOptions != null ? processorOptions : {},
|
|
4925
|
+
routeReplayTraces: true,
|
|
4582
4926
|
...headers ? { headers } : {}
|
|
4583
4927
|
});
|
|
4584
4928
|
const localDebuggerProcessor = createLocalDebuggerSpanProcessor({
|
|
@@ -4661,7 +5005,12 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4661
5005
|
};
|
|
4662
5006
|
|
|
4663
5007
|
export {
|
|
5008
|
+
EVAL_CORRELATION_ID_ATTRIBUTE,
|
|
5009
|
+
withEvalScope,
|
|
5010
|
+
currentEvalScope,
|
|
5011
|
+
evalScopeAttributes,
|
|
4664
5012
|
normalizeFeatureFlags,
|
|
5013
|
+
randomUUID,
|
|
4665
5014
|
runWithTracingSuppressed,
|
|
4666
5015
|
DEFAULT_REQUEST_TIMEOUT_MS,
|
|
4667
5016
|
MAX_RETRY_DELAY_MS,
|
|
@@ -4671,7 +5020,10 @@ export {
|
|
|
4671
5020
|
setDefaultMaxTextFieldChars,
|
|
4672
5021
|
resolveMaxTextFieldChars,
|
|
4673
5022
|
capText,
|
|
5023
|
+
boundedClone,
|
|
4674
5024
|
stringifyBounded,
|
|
5025
|
+
withReplayTraceDestination,
|
|
5026
|
+
currentReplayTraceDestination,
|
|
4675
5027
|
resolveLocalDebuggerBaseUrl,
|
|
4676
5028
|
localDebuggerEnabled,
|
|
4677
5029
|
mirrorPartialEventToLocalDebugger,
|
|
@@ -4682,5 +5034,6 @@ export {
|
|
|
4682
5034
|
withRoutingContext,
|
|
4683
5035
|
package_default,
|
|
4684
5036
|
authHintForKey,
|
|
5037
|
+
withTask,
|
|
4685
5038
|
tracing
|
|
4686
5039
|
};
|