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
package/dist/tracing/index.js
CHANGED
|
@@ -39,7 +39,69 @@ module.exports = __toCommonJS(tracing_exports);
|
|
|
39
39
|
var import_api6 = require("@opentelemetry/api");
|
|
40
40
|
var import_exporter_trace_otlp_http = require("@opentelemetry/exporter-trace-otlp-http");
|
|
41
41
|
|
|
42
|
-
// ../core/dist/chunk-
|
|
42
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
43
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
44
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
45
|
+
var EvalScopeStorage = class {
|
|
46
|
+
constructor() {
|
|
47
|
+
this._als = null;
|
|
48
|
+
this._probed = false;
|
|
49
|
+
}
|
|
50
|
+
maybeAdoptAsyncLocalStorage() {
|
|
51
|
+
if (this._probed) return;
|
|
52
|
+
this._probed = true;
|
|
53
|
+
try {
|
|
54
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
55
|
+
if (!Ctor) return;
|
|
56
|
+
const als = new Ctor();
|
|
57
|
+
als.run(PROBE_SCOPE, () => {
|
|
58
|
+
});
|
|
59
|
+
this._als = als;
|
|
60
|
+
} catch (e) {
|
|
61
|
+
this._als = null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
run(scope, callback) {
|
|
65
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
66
|
+
if (this._als) return this._als.run(scope, callback);
|
|
67
|
+
const previous = this._syncScope;
|
|
68
|
+
this._syncScope = scope;
|
|
69
|
+
try {
|
|
70
|
+
return callback();
|
|
71
|
+
} finally {
|
|
72
|
+
this._syncScope = previous;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
current() {
|
|
76
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
77
|
+
if (this._als) return this._als.getStore();
|
|
78
|
+
return this._syncScope;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
82
|
+
function evalScopeStorage() {
|
|
83
|
+
const holder = globalThis;
|
|
84
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
85
|
+
if (!storage) {
|
|
86
|
+
storage = new EvalScopeStorage();
|
|
87
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
88
|
+
}
|
|
89
|
+
return storage;
|
|
90
|
+
}
|
|
91
|
+
function currentEvalScope() {
|
|
92
|
+
try {
|
|
93
|
+
return evalScopeStorage().current();
|
|
94
|
+
} catch (e) {
|
|
95
|
+
return void 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function evalScopeAttributes() {
|
|
99
|
+
const scope = currentEvalScope();
|
|
100
|
+
if (!scope) return {};
|
|
101
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ../core/dist/chunk-T53LQAH7.js
|
|
43
105
|
function normalizeFeatureFlags(input) {
|
|
44
106
|
if (Array.isArray(input)) {
|
|
45
107
|
return Object.fromEntries(input.map((name) => [name, "true"]));
|
|
@@ -462,6 +524,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
462
524
|
const resp = await runWithTracingSuppressed(
|
|
463
525
|
() => fetch(url, {
|
|
464
526
|
method: "POST",
|
|
527
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
465
528
|
headers: {
|
|
466
529
|
"Content-Type": "application/json",
|
|
467
530
|
...headers
|
|
@@ -590,6 +653,55 @@ function attrDouble(key, value) {
|
|
|
590
653
|
if (!Number.isFinite(value)) return void 0;
|
|
591
654
|
return { key, value: { doubleValue: value } };
|
|
592
655
|
}
|
|
656
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
657
|
+
function state() {
|
|
658
|
+
const holder = globalThis;
|
|
659
|
+
let current = holder[STATE_KEY];
|
|
660
|
+
if (!current) {
|
|
661
|
+
let storage = null;
|
|
662
|
+
try {
|
|
663
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
664
|
+
if (Ctor) storage = new Ctor();
|
|
665
|
+
} catch (e) {
|
|
666
|
+
storage = null;
|
|
667
|
+
}
|
|
668
|
+
current = {
|
|
669
|
+
storage,
|
|
670
|
+
syncDestination: void 0,
|
|
671
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
672
|
+
};
|
|
673
|
+
holder[STATE_KEY] = current;
|
|
674
|
+
}
|
|
675
|
+
return current;
|
|
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
|
+
}
|
|
593
705
|
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
594
706
|
var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
|
|
595
707
|
var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
|
|
@@ -655,19 +767,23 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
655
767
|
function localDebuggerEnabled(baseUrl) {
|
|
656
768
|
return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
|
|
657
769
|
}
|
|
770
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
658
771
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
659
772
|
var _a;
|
|
660
773
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
661
|
-
if (!baseUrl) return;
|
|
662
|
-
|
|
774
|
+
if (!baseUrl) return Promise.resolve();
|
|
775
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
663
776
|
maxAttempts: 1,
|
|
664
777
|
debug: (_a = options.debug) != null ? _a : false,
|
|
665
|
-
sdkName: options.sdkName
|
|
778
|
+
sdkName: options.sdkName,
|
|
779
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
666
780
|
}).catch(() => {
|
|
667
781
|
});
|
|
668
782
|
}
|
|
669
783
|
function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
670
784
|
var _a, _b;
|
|
785
|
+
const destination = currentReplayTraceDestination();
|
|
786
|
+
if (destination && destination.kind !== "workshop") return;
|
|
671
787
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
672
788
|
if (!baseUrl) return;
|
|
673
789
|
void postJson(
|
|
@@ -1096,570 +1212,179 @@ var import_instrumentation_anthropic = require("@traceloop/instrumentation-anthr
|
|
|
1096
1212
|
var import_instrumentation_bedrock = require("@traceloop/instrumentation-bedrock");
|
|
1097
1213
|
var import_instrumentation_chromadb = require("@traceloop/instrumentation-chromadb");
|
|
1098
1214
|
var import_instrumentation_cohere = require("@traceloop/instrumentation-cohere");
|
|
1099
|
-
var import_instrumentation_openai = require("@traceloop/instrumentation-openai");
|
|
1100
1215
|
var import_instrumentation_langchain = require("@traceloop/instrumentation-langchain");
|
|
1101
1216
|
var import_instrumentation_llamaindex = require("@traceloop/instrumentation-llamaindex");
|
|
1217
|
+
var import_instrumentation_openai = require("@traceloop/instrumentation-openai");
|
|
1102
1218
|
var import_instrumentation_pinecone = require("@traceloop/instrumentation-pinecone");
|
|
1103
1219
|
var import_instrumentation_qdrant = require("@traceloop/instrumentation-qdrant");
|
|
1104
1220
|
var import_instrumentation_together = require("@traceloop/instrumentation-together");
|
|
1105
1221
|
var import_instrumentation_vertexai = require("@traceloop/instrumentation-vertexai");
|
|
1222
|
+
var import_weakref = require("weakref");
|
|
1106
1223
|
|
|
1107
|
-
// src/
|
|
1108
|
-
var
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
var import_instrumentation = require("@opentelemetry/instrumentation");
|
|
1112
|
-
var resourceModule = __toESM(require("@opentelemetry/resources"));
|
|
1113
|
-
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
1114
|
-
var import_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
|
|
1115
|
-
var import_ai_semantic_conventions = require("@traceloop/ai-semantic-conventions");
|
|
1116
|
-
var ALL_INSTRUMENTATION_LIBRARIES = "all";
|
|
1117
|
-
var TRACER_NAME = "@traceloop/node-server-sdk";
|
|
1118
|
-
var WORKFLOW_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.workflowName");
|
|
1119
|
-
var ENTITY_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.entityName");
|
|
1120
|
-
var ASSOCIATION_PROPERTIES_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.associationProperties");
|
|
1121
|
-
var INSTRUMENTATION_LIBRARIES = [
|
|
1122
|
-
"ai",
|
|
1123
|
-
"@traceloop/node-server-sdk",
|
|
1124
|
-
"@traceloop/instrumentation-openai",
|
|
1125
|
-
"@traceloop/instrumentation-langchain",
|
|
1126
|
-
"@traceloop/instrumentation-chroma",
|
|
1127
|
-
"@traceloop/instrumentation-chromadb",
|
|
1128
|
-
"@traceloop/instrumentation-anthropic",
|
|
1129
|
-
"@traceloop/instrumentation-llamaindex",
|
|
1130
|
-
"@traceloop/instrumentation-vertexai",
|
|
1131
|
-
"@traceloop/instrumentation-bedrock",
|
|
1132
|
-
"@traceloop/instrumentation-cohere",
|
|
1133
|
-
"@traceloop/instrumentation-pinecone",
|
|
1134
|
-
"@traceloop/instrumentation-qdrant",
|
|
1135
|
-
"@traceloop/instrumentation-together",
|
|
1136
|
-
TRACER_NAME,
|
|
1137
|
-
"traceloop.tracer"
|
|
1138
|
-
];
|
|
1139
|
-
var AI_GENERATE_TEXT = "ai.generateText.doGenerate";
|
|
1140
|
-
var AI_STREAM_TEXT = "ai.streamText.doStream";
|
|
1141
|
-
var AI_RESPONSE_TEXT = "ai.response.text";
|
|
1142
|
-
var AI_PROMPT_MESSAGES = "ai.prompt.messages";
|
|
1143
|
-
var AI_PROMPT_TOKENS = "ai.usage.promptTokens";
|
|
1144
|
-
var AI_COMPLETION_TOKENS = "ai.usage.completionTokens";
|
|
1145
|
-
var AI_MODEL_PROVIDER = "ai.model.provider";
|
|
1146
|
-
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.state");
|
|
1147
|
-
function getState() {
|
|
1148
|
-
var _a;
|
|
1149
|
-
const holder = globalThis;
|
|
1150
|
-
(_a = holder[STATE_KEY]) != null ? _a : holder[STATE_KEY] = {};
|
|
1151
|
-
return holder[STATE_KEY];
|
|
1152
|
-
}
|
|
1153
|
-
function parseHeaders(value) {
|
|
1154
|
-
const headers = {};
|
|
1155
|
-
if (!value) return headers;
|
|
1156
|
-
for (const pair of value.split(",")) {
|
|
1157
|
-
const separator = pair.indexOf("=");
|
|
1158
|
-
if (separator <= 0) continue;
|
|
1159
|
-
try {
|
|
1160
|
-
const key = decodeURIComponent(pair.slice(0, separator).trim());
|
|
1161
|
-
const val = decodeURIComponent(pair.slice(separator + 1).trim());
|
|
1162
|
-
if (key && val) headers[key] = val;
|
|
1163
|
-
} catch (e) {
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
return headers;
|
|
1224
|
+
// src/lib/inject-als.ts
|
|
1225
|
+
var import_node_async_hooks = require("async_hooks");
|
|
1226
|
+
if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
1227
|
+
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = import_node_async_hooks.AsyncLocalStorage;
|
|
1167
1228
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
} catch (e) {
|
|
1173
|
-
return "[unserializable]";
|
|
1174
|
-
}
|
|
1229
|
+
|
|
1230
|
+
// src/tracing/direct/http.ts
|
|
1231
|
+
function wait2(ms) {
|
|
1232
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1175
1233
|
}
|
|
1176
|
-
function
|
|
1177
|
-
if (
|
|
1178
|
-
|
|
1179
|
-
if (typeof factory === "function") return factory(attributes);
|
|
1180
|
-
}
|
|
1181
|
-
return new resourceModule.Resource(attributes);
|
|
1234
|
+
function formatEndpoint2(endpoint) {
|
|
1235
|
+
if (!endpoint) return void 0;
|
|
1236
|
+
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
1182
1237
|
}
|
|
1183
|
-
function
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
if ("detectResources" in resourceModule && typeof resourceModule.detectResources === "function" && "envDetector" in resourceModule) {
|
|
1195
|
-
const detected = resourceModule.detectResources({
|
|
1196
|
-
detectors: [
|
|
1197
|
-
resourceModule.envDetector,
|
|
1198
|
-
resourceModule.processDetector,
|
|
1199
|
-
resourceModule.hostDetector
|
|
1200
|
-
]
|
|
1201
|
-
});
|
|
1202
|
-
if (!(detected instanceof Promise)) {
|
|
1203
|
-
return detected;
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
} catch (e) {
|
|
1238
|
+
function parseRetryAfter2(headers) {
|
|
1239
|
+
var _a;
|
|
1240
|
+
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
1241
|
+
if (!value) return void 0;
|
|
1242
|
+
const asNumber = Number(value);
|
|
1243
|
+
if (!Number.isNaN(asNumber)) return asNumber * 1e3;
|
|
1244
|
+
const asDate = new Date(value).getTime();
|
|
1245
|
+
if (!Number.isNaN(asDate)) {
|
|
1246
|
+
const delta = asDate - Date.now();
|
|
1247
|
+
return delta > 0 ? delta : 0;
|
|
1207
1248
|
}
|
|
1208
1249
|
return void 0;
|
|
1209
1250
|
}
|
|
1210
|
-
function
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
case "info":
|
|
1215
|
-
return import_api.DiagLogLevel.INFO;
|
|
1216
|
-
case "warn":
|
|
1217
|
-
return import_api.DiagLogLevel.WARN;
|
|
1218
|
-
default:
|
|
1219
|
-
return import_api.DiagLogLevel.ERROR;
|
|
1251
|
+
function getRetryDelayMs2(attemptNumber, previousError) {
|
|
1252
|
+
if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
|
|
1253
|
+
const v = previousError.retryAfterMs;
|
|
1254
|
+
if (typeof v === "number") return Math.min(Math.max(0, v), MAX_RETRY_DELAY_MS);
|
|
1220
1255
|
}
|
|
1256
|
+
if (attemptNumber <= 1) return 0;
|
|
1257
|
+
const base = 500;
|
|
1258
|
+
const factor = Math.pow(2, attemptNumber - 2);
|
|
1259
|
+
return Math.min(base * factor, MAX_RETRY_DELAY_MS);
|
|
1221
1260
|
}
|
|
1222
|
-
function
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1261
|
+
async function withRetry2(operation, opName, opts) {
|
|
1262
|
+
let lastError = void 0;
|
|
1263
|
+
for (let attemptNumber = 1; attemptNumber <= opts.maxAttempts; attemptNumber++) {
|
|
1264
|
+
if (attemptNumber > 1) {
|
|
1265
|
+
const delay = getRetryDelayMs2(attemptNumber, lastError);
|
|
1266
|
+
if (opts.debug) {
|
|
1267
|
+
console.warn(
|
|
1268
|
+
`[raindrop] ${opName} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
if (delay > 0) await wait2(delay);
|
|
1272
|
+
} else if (opts.debug) {
|
|
1273
|
+
console.log(`[raindrop] ${opName} attempt ${attemptNumber}/${opts.maxAttempts}`);
|
|
1233
1274
|
}
|
|
1234
|
-
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_COMPLETIONS}.0.role`] = "assistant";
|
|
1235
|
-
delete attributes[AI_RESPONSE_TEXT];
|
|
1236
|
-
}
|
|
1237
|
-
if (AI_PROMPT_MESSAGES in attributes) {
|
|
1238
1275
|
try {
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.role`] = role;
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1276
|
+
return await operation();
|
|
1277
|
+
} catch (err) {
|
|
1278
|
+
lastError = err;
|
|
1279
|
+
if (opts.debug) {
|
|
1280
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1281
|
+
console.warn(
|
|
1282
|
+
`[raindrop] ${opName} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
|
|
1283
|
+
);
|
|
1250
1284
|
}
|
|
1251
|
-
|
|
1252
|
-
} catch (e) {
|
|
1285
|
+
if (attemptNumber === opts.maxAttempts) break;
|
|
1253
1286
|
}
|
|
1254
1287
|
}
|
|
1255
|
-
|
|
1256
|
-
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS] = Number(attributes[AI_PROMPT_TOKENS]);
|
|
1257
|
-
delete attributes[AI_PROMPT_TOKENS];
|
|
1258
|
-
}
|
|
1259
|
-
if (AI_COMPLETION_TOKENS in attributes) {
|
|
1260
|
-
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] = Number(attributes[AI_COMPLETION_TOKENS]);
|
|
1261
|
-
delete attributes[AI_COMPLETION_TOKENS];
|
|
1262
|
-
}
|
|
1263
|
-
const prompt = attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS];
|
|
1264
|
-
const completion = attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS];
|
|
1265
|
-
if (prompt !== void 0 && completion !== void 0) {
|
|
1266
|
-
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_TOTAL_TOKENS] = Number(prompt) + Number(completion);
|
|
1267
|
-
}
|
|
1268
|
-
if (AI_MODEL_PROVIDER in attributes) {
|
|
1269
|
-
const vendor = String(attributes[AI_MODEL_PROVIDER]);
|
|
1270
|
-
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_SYSTEM] = vendor.startsWith("openai") ? "OpenAI" : vendor;
|
|
1271
|
-
delete attributes[AI_MODEL_PROVIDER];
|
|
1272
|
-
}
|
|
1273
|
-
Object.defineProperty(span, "name", {
|
|
1274
|
-
configurable: true,
|
|
1275
|
-
value: names[span.name],
|
|
1276
|
-
writable: true
|
|
1277
|
-
});
|
|
1278
|
-
return span;
|
|
1288
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
1279
1289
|
}
|
|
1280
|
-
function
|
|
1290
|
+
async function postJson2(url, body, headers, opts) {
|
|
1281
1291
|
var _a;
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
const properties = active.getValue(ASSOCIATION_PROPERTIES_KEY);
|
|
1307
|
-
if (properties && typeof properties === "object") {
|
|
1308
|
-
for (const [key, value] of Object.entries(properties)) {
|
|
1309
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1310
|
-
span.setAttribute(`${import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.${key}`, value);
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
function createSpanProcessor(options) {
|
|
1316
|
-
var _a, _b;
|
|
1317
|
-
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
1318
|
-
const apiKey = options.apiKey || process.env.TRACELOOP_API_KEY;
|
|
1319
|
-
const resolvedHeaders = (_a = options.headers) != null ? _a : process.env.TRACELOOP_HEADERS ? parseHeaders(process.env.TRACELOOP_HEADERS) : { Authorization: `Bearer ${apiKey}` };
|
|
1320
|
-
const exporter = (_b = options.exporter) != null ? _b : new import_exporter_trace_otlp_proto.OTLPTraceExporter({ url: `${baseUrl}/v1/traces`, headers: resolvedHeaders });
|
|
1321
|
-
const processor = options.disableBatch ? new import_sdk_trace_base.SimpleSpanProcessor(exporter) : new import_sdk_trace_base.BatchSpanProcessor(exporter);
|
|
1322
|
-
const originalOnStart = processor.onStart.bind(processor);
|
|
1323
|
-
const originalOnEnd = processor.onEnd.bind(processor);
|
|
1324
|
-
processor.onStart = (span, parentContext) => {
|
|
1325
|
-
try {
|
|
1326
|
-
enrichStart(span);
|
|
1327
|
-
originalOnStart(span, parentContext);
|
|
1328
|
-
} catch (e) {
|
|
1329
|
-
}
|
|
1330
|
-
};
|
|
1331
|
-
processor.onEnd = (span) => {
|
|
1332
|
-
var _a2;
|
|
1333
|
-
let outgoing = span;
|
|
1334
|
-
try {
|
|
1335
|
-
const allowed = options.allowedInstrumentationLibraries;
|
|
1336
|
-
if (allowed !== ALL_INSTRUMENTATION_LIBRARIES && ![...INSTRUMENTATION_LIBRARIES, ...allowed != null ? allowed : []].includes((_a2 = scopeName(span)) != null ? _a2 : "")) {
|
|
1337
|
-
return;
|
|
1292
|
+
const opName = `POST ${redactUrlForLog(url)}`;
|
|
1293
|
+
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1294
|
+
await withRetry2(
|
|
1295
|
+
async () => {
|
|
1296
|
+
const resp = await runWithTracingSuppressed(
|
|
1297
|
+
() => fetch(url, {
|
|
1298
|
+
method: "POST",
|
|
1299
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
1300
|
+
headers: {
|
|
1301
|
+
"Content-Type": "application/json",
|
|
1302
|
+
...headers
|
|
1303
|
+
},
|
|
1304
|
+
body: JSON.stringify(body),
|
|
1305
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1306
|
+
})
|
|
1307
|
+
);
|
|
1308
|
+
if (!resp.ok) {
|
|
1309
|
+
const text = await resp.text().catch(() => "");
|
|
1310
|
+
const err = new Error(
|
|
1311
|
+
`HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
|
|
1312
|
+
);
|
|
1313
|
+
const retryAfterMs = parseRetryAfter2(resp.headers);
|
|
1314
|
+
if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
|
|
1315
|
+
throw err;
|
|
1338
1316
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
originalOnEnd(outgoing);
|
|
1344
|
-
} catch (e) {
|
|
1345
|
-
}
|
|
1346
|
-
};
|
|
1347
|
-
return processor;
|
|
1317
|
+
},
|
|
1318
|
+
opName,
|
|
1319
|
+
opts
|
|
1320
|
+
);
|
|
1348
1321
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
if (options.logLevel) import_api.diag.setLogger(new import_api.DiagConsoleLogger(), logLevel(options.logLevel));
|
|
1355
|
-
if (options.tracingEnabled === false) return;
|
|
1356
|
-
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
1357
|
-
state.defaultProcessor = createSpanProcessor({
|
|
1358
|
-
...options,
|
|
1359
|
-
baseUrl,
|
|
1360
|
-
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
1361
|
-
});
|
|
1362
|
-
const serviceResource = createResource({
|
|
1363
|
-
"service.name": options.appName || process.env.npm_package_name || "unknown_service"
|
|
1364
|
-
});
|
|
1365
|
-
const detectedResource = detectRuntimeResource();
|
|
1366
|
-
state.provider = new import_sdk_trace_node.NodeTracerProvider({
|
|
1367
|
-
// Detected attributes win over the configured resource, matching
|
|
1368
|
-
// sdk-node's `this._resource.merge(detectResourcesSync(...))` so
|
|
1369
|
-
// OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES can still override appName.
|
|
1370
|
-
resource: detectedResource ? serviceResource.merge(detectedResource) : serviceResource,
|
|
1371
|
-
spanProcessors: [state.defaultProcessor, ...options.processor ? [options.processor] : []]
|
|
1372
|
-
});
|
|
1373
|
-
state.provider.register({
|
|
1374
|
-
contextManager: options.contextManager,
|
|
1375
|
-
propagator: options.propagator
|
|
1376
|
-
});
|
|
1377
|
-
const instrumentations = (_a = options.instrumentations) != null ? _a : [];
|
|
1378
|
-
if (contentCaptureDisabled(options)) {
|
|
1379
|
-
for (const instrumentation of instrumentations) {
|
|
1380
|
-
try {
|
|
1381
|
-
const config = {
|
|
1382
|
-
...instrumentation.getConfig(),
|
|
1383
|
-
traceContent: false
|
|
1384
|
-
};
|
|
1385
|
-
instrumentation.setConfig(config);
|
|
1386
|
-
} catch (e) {
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
(0, import_instrumentation.registerInstrumentations)({ instrumentations });
|
|
1322
|
+
|
|
1323
|
+
// src/tracing/direct/ids.ts
|
|
1324
|
+
function getCrypto2() {
|
|
1325
|
+
const c = globalThis.crypto;
|
|
1326
|
+
return c;
|
|
1391
1327
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
const
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
} catch (e) {
|
|
1328
|
+
function randomBytes2(length) {
|
|
1329
|
+
const cryptoObj = getCrypto2();
|
|
1330
|
+
const out = new Uint8Array(length);
|
|
1331
|
+
if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
|
|
1332
|
+
cryptoObj.getRandomValues(out);
|
|
1333
|
+
return out;
|
|
1399
1334
|
}
|
|
1335
|
+
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
1336
|
+
return out;
|
|
1400
1337
|
}
|
|
1401
|
-
function
|
|
1402
|
-
|
|
1403
|
-
if (
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1406
|
-
const parentPath = entityContext.getValue(ENTITY_NAME_KEY);
|
|
1407
|
-
if (type === import_ai_semantic_conventions.TraceloopSpanKindValues.TASK || type === import_ai_semantic_conventions.TraceloopSpanKindValues.TOOL) {
|
|
1408
|
-
entityContext = entityContext.setValue(
|
|
1409
|
-
ENTITY_NAME_KEY,
|
|
1410
|
-
`${typeof parentPath === "string" ? `${parentPath}.` : ""}${config.name}`
|
|
1411
|
-
);
|
|
1338
|
+
function base64Encode2(bytes) {
|
|
1339
|
+
const maybeBuffer = globalThis.Buffer;
|
|
1340
|
+
if (maybeBuffer) {
|
|
1341
|
+
return maybeBuffer.from(bytes).toString("base64");
|
|
1412
1342
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1343
|
+
let binary = "";
|
|
1344
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
1345
|
+
binary += String.fromCharCode(bytes[i2]);
|
|
1415
1346
|
}
|
|
1416
|
-
|
|
1417
|
-
|
|
1347
|
+
const btoaFn = globalThis.btoa;
|
|
1348
|
+
if (typeof btoaFn === "function") return btoaFn(binary);
|
|
1349
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1350
|
+
let out = "";
|
|
1351
|
+
let i = 0;
|
|
1352
|
+
while (i < binary.length) {
|
|
1353
|
+
const c1 = binary.charCodeAt(i++) & 255;
|
|
1354
|
+
const c2 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1355
|
+
const c3 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1356
|
+
const e1 = c1 >> 2;
|
|
1357
|
+
const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
|
|
1358
|
+
const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
|
|
1359
|
+
const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
|
|
1360
|
+
out += alphabet.charAt(e1);
|
|
1361
|
+
out += alphabet.charAt(e2);
|
|
1362
|
+
out += e3 === 64 ? "=" : alphabet.charAt(e3);
|
|
1363
|
+
out += e4 === 64 ? "=" : alphabet.charAt(e4);
|
|
1418
1364
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1365
|
+
return out;
|
|
1366
|
+
}
|
|
1367
|
+
function base64ToHex2(base64) {
|
|
1368
|
+
const maybeBuffer = globalThis.Buffer;
|
|
1369
|
+
if (maybeBuffer) {
|
|
1370
|
+
return maybeBuffer.from(base64, "base64").toString("hex");
|
|
1421
1371
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_SPAN_KIND, type);
|
|
1429
|
-
if (type === import_ai_semantic_conventions.TraceloopSpanKindValues.WORKFLOW) {
|
|
1430
|
-
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_WORKFLOW_NAME, config.name);
|
|
1431
|
-
}
|
|
1432
|
-
if (config.version !== void 0) span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_VERSION, config.version);
|
|
1433
|
-
const input = (_a = config.inputParameters) != null ? _a : args;
|
|
1434
|
-
if (shouldSendTraceContent()) {
|
|
1435
|
-
span.setAttribute(
|
|
1436
|
-
import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_INPUT,
|
|
1437
|
-
safeStringify(input.length === 1 && input[0] !== null && typeof input[0] === "object" && !(input[0] instanceof Map) ? { args: [], kwargs: input[0] } : { args: input, kwargs: {} })
|
|
1438
|
-
);
|
|
1439
|
-
}
|
|
1440
|
-
} catch (e) {
|
|
1441
|
-
}
|
|
1442
|
-
let result;
|
|
1443
|
-
try {
|
|
1444
|
-
callbackStarted = true;
|
|
1445
|
-
result = fn(...args);
|
|
1446
|
-
} catch (error) {
|
|
1447
|
-
try {
|
|
1448
|
-
span.end();
|
|
1449
|
-
} catch (e) {
|
|
1450
|
-
}
|
|
1451
|
-
throw error;
|
|
1452
|
-
}
|
|
1453
|
-
if (result instanceof Promise) {
|
|
1454
|
-
return result.then(
|
|
1455
|
-
(value) => {
|
|
1456
|
-
try {
|
|
1457
|
-
if (shouldSendTraceContent()) span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(value));
|
|
1458
|
-
span.end();
|
|
1459
|
-
} catch (e) {
|
|
1460
|
-
}
|
|
1461
|
-
return value;
|
|
1462
|
-
},
|
|
1463
|
-
(error) => {
|
|
1464
|
-
try {
|
|
1465
|
-
span.end();
|
|
1466
|
-
} catch (e) {
|
|
1467
|
-
}
|
|
1468
|
-
throw error;
|
|
1469
|
-
}
|
|
1470
|
-
);
|
|
1471
|
-
}
|
|
1472
|
-
try {
|
|
1473
|
-
if (shouldSendTraceContent()) span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(result));
|
|
1474
|
-
span.end();
|
|
1475
|
-
} catch (e) {
|
|
1372
|
+
const atobFn = globalThis.atob;
|
|
1373
|
+
if (typeof atobFn === "function") {
|
|
1374
|
+
const binary = atobFn(base64);
|
|
1375
|
+
let hex = "";
|
|
1376
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1377
|
+
hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
|
|
1476
1378
|
}
|
|
1477
|
-
return
|
|
1478
|
-
};
|
|
1479
|
-
try {
|
|
1480
|
-
const tracer = import_api.trace.getTracer(TRACER_NAME);
|
|
1481
|
-
return import_api.context.with(
|
|
1482
|
-
entityContext,
|
|
1483
|
-
() => tracer.startActiveSpan(`${config.name}.${type}`, {}, entityContext, run)
|
|
1484
|
-
);
|
|
1485
|
-
} catch (error) {
|
|
1486
|
-
if (callbackStarted) throw error;
|
|
1487
|
-
return fn(...args);
|
|
1379
|
+
return hex;
|
|
1488
1380
|
}
|
|
1489
|
-
|
|
1490
|
-
function withTask(config, fn, ...args) {
|
|
1491
|
-
return withEntity(import_ai_semantic_conventions.TraceloopSpanKindValues.TASK, config, fn, args);
|
|
1492
|
-
}
|
|
1493
|
-
function withTool(config, fn, ...args) {
|
|
1494
|
-
return withEntity(import_ai_semantic_conventions.TraceloopSpanKindValues.TOOL, config, fn, args);
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
// src/tracing/tracer-core.ts
|
|
1498
|
-
var import_weakref = require("weakref");
|
|
1499
|
-
|
|
1500
|
-
// src/lib/inject-als.ts
|
|
1501
|
-
var import_node_async_hooks = require("async_hooks");
|
|
1502
|
-
if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
1503
|
-
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = import_node_async_hooks.AsyncLocalStorage;
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
// src/tracing/direct/http.ts
|
|
1507
|
-
function wait2(ms) {
|
|
1508
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1509
|
-
}
|
|
1510
|
-
function formatEndpoint2(endpoint) {
|
|
1511
|
-
if (!endpoint) return void 0;
|
|
1512
|
-
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
1513
|
-
}
|
|
1514
|
-
function parseRetryAfter2(headers) {
|
|
1515
|
-
var _a;
|
|
1516
|
-
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
1517
|
-
if (!value) return void 0;
|
|
1518
|
-
const asNumber = Number(value);
|
|
1519
|
-
if (!Number.isNaN(asNumber)) return asNumber * 1e3;
|
|
1520
|
-
const asDate = new Date(value).getTime();
|
|
1521
|
-
if (!Number.isNaN(asDate)) {
|
|
1522
|
-
const delta = asDate - Date.now();
|
|
1523
|
-
return delta > 0 ? delta : 0;
|
|
1524
|
-
}
|
|
1525
|
-
return void 0;
|
|
1526
|
-
}
|
|
1527
|
-
function getRetryDelayMs2(attemptNumber, previousError) {
|
|
1528
|
-
if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
|
|
1529
|
-
const v = previousError.retryAfterMs;
|
|
1530
|
-
if (typeof v === "number") return Math.min(Math.max(0, v), MAX_RETRY_DELAY_MS);
|
|
1531
|
-
}
|
|
1532
|
-
if (attemptNumber <= 1) return 0;
|
|
1533
|
-
const base = 500;
|
|
1534
|
-
const factor = Math.pow(2, attemptNumber - 2);
|
|
1535
|
-
return Math.min(base * factor, MAX_RETRY_DELAY_MS);
|
|
1536
|
-
}
|
|
1537
|
-
async function withRetry2(operation, opName, opts) {
|
|
1538
|
-
let lastError = void 0;
|
|
1539
|
-
for (let attemptNumber = 1; attemptNumber <= opts.maxAttempts; attemptNumber++) {
|
|
1540
|
-
if (attemptNumber > 1) {
|
|
1541
|
-
const delay = getRetryDelayMs2(attemptNumber, lastError);
|
|
1542
|
-
if (opts.debug) {
|
|
1543
|
-
console.warn(
|
|
1544
|
-
`[raindrop] ${opName} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`
|
|
1545
|
-
);
|
|
1546
|
-
}
|
|
1547
|
-
if (delay > 0) await wait2(delay);
|
|
1548
|
-
} else if (opts.debug) {
|
|
1549
|
-
console.log(`[raindrop] ${opName} attempt ${attemptNumber}/${opts.maxAttempts}`);
|
|
1550
|
-
}
|
|
1551
|
-
try {
|
|
1552
|
-
return await operation();
|
|
1553
|
-
} catch (err) {
|
|
1554
|
-
lastError = err;
|
|
1555
|
-
if (opts.debug) {
|
|
1556
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1557
|
-
console.warn(
|
|
1558
|
-
`[raindrop] ${opName} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
if (attemptNumber === opts.maxAttempts) break;
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
1565
|
-
}
|
|
1566
|
-
async function postJson2(url, body, headers, opts) {
|
|
1567
|
-
var _a;
|
|
1568
|
-
const opName = `POST ${redactUrlForLog(url)}`;
|
|
1569
|
-
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1570
|
-
await withRetry2(
|
|
1571
|
-
async () => {
|
|
1572
|
-
const resp = await runWithTracingSuppressed(
|
|
1573
|
-
() => fetch(url, {
|
|
1574
|
-
method: "POST",
|
|
1575
|
-
headers: {
|
|
1576
|
-
"Content-Type": "application/json",
|
|
1577
|
-
...headers
|
|
1578
|
-
},
|
|
1579
|
-
body: JSON.stringify(body),
|
|
1580
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
1581
|
-
})
|
|
1582
|
-
);
|
|
1583
|
-
if (!resp.ok) {
|
|
1584
|
-
const text = await resp.text().catch(() => "");
|
|
1585
|
-
const err = new Error(
|
|
1586
|
-
`HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
|
|
1587
|
-
);
|
|
1588
|
-
const retryAfterMs = parseRetryAfter2(resp.headers);
|
|
1589
|
-
if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
|
|
1590
|
-
throw err;
|
|
1591
|
-
}
|
|
1592
|
-
},
|
|
1593
|
-
opName,
|
|
1594
|
-
opts
|
|
1595
|
-
);
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// src/tracing/direct/ids.ts
|
|
1599
|
-
function getCrypto2() {
|
|
1600
|
-
const c = globalThis.crypto;
|
|
1601
|
-
return c;
|
|
1602
|
-
}
|
|
1603
|
-
function randomBytes2(length) {
|
|
1604
|
-
const cryptoObj = getCrypto2();
|
|
1605
|
-
const out = new Uint8Array(length);
|
|
1606
|
-
if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
|
|
1607
|
-
cryptoObj.getRandomValues(out);
|
|
1608
|
-
return out;
|
|
1609
|
-
}
|
|
1610
|
-
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
1611
|
-
return out;
|
|
1612
|
-
}
|
|
1613
|
-
function base64Encode2(bytes) {
|
|
1614
|
-
const maybeBuffer = globalThis.Buffer;
|
|
1615
|
-
if (maybeBuffer) {
|
|
1616
|
-
return maybeBuffer.from(bytes).toString("base64");
|
|
1617
|
-
}
|
|
1618
|
-
let binary = "";
|
|
1619
|
-
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
1620
|
-
binary += String.fromCharCode(bytes[i2]);
|
|
1621
|
-
}
|
|
1622
|
-
const btoaFn = globalThis.btoa;
|
|
1623
|
-
if (typeof btoaFn === "function") return btoaFn(binary);
|
|
1624
|
-
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1625
|
-
let out = "";
|
|
1626
|
-
let i = 0;
|
|
1627
|
-
while (i < binary.length) {
|
|
1628
|
-
const c1 = binary.charCodeAt(i++) & 255;
|
|
1629
|
-
const c2 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1630
|
-
const c3 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
|
|
1631
|
-
const e1 = c1 >> 2;
|
|
1632
|
-
const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
|
|
1633
|
-
const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
|
|
1634
|
-
const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
|
|
1635
|
-
out += alphabet.charAt(e1);
|
|
1636
|
-
out += alphabet.charAt(e2);
|
|
1637
|
-
out += e3 === 64 ? "=" : alphabet.charAt(e3);
|
|
1638
|
-
out += e4 === 64 ? "=" : alphabet.charAt(e4);
|
|
1639
|
-
}
|
|
1640
|
-
return out;
|
|
1641
|
-
}
|
|
1642
|
-
function base64ToHex2(base64) {
|
|
1643
|
-
const maybeBuffer = globalThis.Buffer;
|
|
1644
|
-
if (maybeBuffer) {
|
|
1645
|
-
return maybeBuffer.from(base64, "base64").toString("hex");
|
|
1646
|
-
}
|
|
1647
|
-
const atobFn = globalThis.atob;
|
|
1648
|
-
if (typeof atobFn === "function") {
|
|
1649
|
-
const binary = atobFn(base64);
|
|
1650
|
-
let hex = "";
|
|
1651
|
-
for (let i = 0; i < binary.length; i++) {
|
|
1652
|
-
hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
|
|
1653
|
-
}
|
|
1654
|
-
return hex;
|
|
1655
|
-
}
|
|
1656
|
-
throw new Error("No base64 decoder available in this runtime");
|
|
1381
|
+
throw new Error("No base64 decoder available in this runtime");
|
|
1657
1382
|
}
|
|
1658
1383
|
|
|
1659
1384
|
// package.json
|
|
1660
1385
|
var package_default = {
|
|
1661
1386
|
name: "raindrop-ai",
|
|
1662
|
-
version: "0.
|
|
1387
|
+
version: "0.5.0",
|
|
1663
1388
|
main: "dist/index.js",
|
|
1664
1389
|
module: "dist/index.mjs",
|
|
1665
1390
|
types: "dist/index.d.ts",
|
|
@@ -1670,9 +1395,14 @@ var package_default = {
|
|
|
1670
1395
|
},
|
|
1671
1396
|
exports: {
|
|
1672
1397
|
".": {
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1398
|
+
import: {
|
|
1399
|
+
types: "./dist/index.d.mts",
|
|
1400
|
+
default: "./dist/index.mjs"
|
|
1401
|
+
},
|
|
1402
|
+
require: {
|
|
1403
|
+
types: "./dist/index.d.ts",
|
|
1404
|
+
default: "./dist/index.js"
|
|
1405
|
+
}
|
|
1676
1406
|
},
|
|
1677
1407
|
"./tracing": {
|
|
1678
1408
|
types: "./dist/tracing/index.d.ts",
|
|
@@ -1712,8 +1442,8 @@ var package_default = {
|
|
|
1712
1442
|
"@raindrop-ai/core": "workspace:*",
|
|
1713
1443
|
"@raindrop-ai/redact-pii": "workspace:*",
|
|
1714
1444
|
"@raindrop-ai/schemas": "workspace:*",
|
|
1715
|
-
ai: "^6.0.0",
|
|
1716
1445
|
"@types/node": "^20.11.17",
|
|
1446
|
+
ai: "^6.0.0",
|
|
1717
1447
|
msw: "^2.12.8",
|
|
1718
1448
|
tsup: "^8.4.0",
|
|
1719
1449
|
tsx: "^4.20.3",
|
|
@@ -1722,6 +1452,7 @@ var package_default = {
|
|
|
1722
1452
|
vitest: "^4.0.10"
|
|
1723
1453
|
},
|
|
1724
1454
|
dependencies: {
|
|
1455
|
+
"@jitl/quickjs-singlefile-cjs-release-sync": "0.32.0",
|
|
1725
1456
|
"@opentelemetry/api": "^1.9.0",
|
|
1726
1457
|
"@opentelemetry/core": "^1.30.1",
|
|
1727
1458
|
"@opentelemetry/exporter-trace-otlp-http": "^0.57.2",
|
|
@@ -1732,16 +1463,17 @@ var package_default = {
|
|
|
1732
1463
|
"@opentelemetry/sdk-trace-node": "^1.30.1",
|
|
1733
1464
|
"@traceloop/ai-semantic-conventions": "0.19.0-otel-v1",
|
|
1734
1465
|
"@traceloop/instrumentation-anthropic": "0.19.0-otel-v1",
|
|
1735
|
-
"@traceloop/instrumentation-openai": "0.19.0-otel-v1",
|
|
1736
|
-
"@traceloop/instrumentation-cohere": "0.19.0-otel-v1",
|
|
1737
1466
|
"@traceloop/instrumentation-bedrock": "0.19.0-otel-v1",
|
|
1738
|
-
"@traceloop/instrumentation-vertexai": "0.19.0-otel-v1",
|
|
1739
|
-
"@traceloop/instrumentation-pinecone": "0.19.0-otel-v1",
|
|
1740
1467
|
"@traceloop/instrumentation-chromadb": "0.19.0-otel-v1",
|
|
1741
|
-
"@traceloop/instrumentation-
|
|
1742
|
-
"@traceloop/instrumentation-together": "0.19.0-otel-v1",
|
|
1468
|
+
"@traceloop/instrumentation-cohere": "0.19.0-otel-v1",
|
|
1743
1469
|
"@traceloop/instrumentation-langchain": "0.19.0-otel-v1",
|
|
1744
1470
|
"@traceloop/instrumentation-llamaindex": "0.19.0-otel-v1",
|
|
1471
|
+
"@traceloop/instrumentation-openai": "0.19.0-otel-v1",
|
|
1472
|
+
"@traceloop/instrumentation-pinecone": "0.19.0-otel-v1",
|
|
1473
|
+
"@traceloop/instrumentation-qdrant": "0.19.0-otel-v1",
|
|
1474
|
+
"@traceloop/instrumentation-together": "0.19.0-otel-v1",
|
|
1475
|
+
"@traceloop/instrumentation-vertexai": "0.19.0-otel-v1",
|
|
1476
|
+
"quickjs-emscripten-core": "0.32.0",
|
|
1745
1477
|
weakref: "^0.2.1",
|
|
1746
1478
|
zod: "^3.23.8"
|
|
1747
1479
|
},
|
|
@@ -1831,520 +1563,1063 @@ function buildExportTraceServiceRequest2(spans) {
|
|
|
1831
1563
|
scope: { name: SERVICE_NAME, version: libraryVersion },
|
|
1832
1564
|
spans
|
|
1833
1565
|
}
|
|
1834
|
-
]
|
|
1566
|
+
]
|
|
1567
|
+
}
|
|
1568
|
+
]
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
// src/tracing/direct/context.ts
|
|
1573
|
+
var import_api = require("@opentelemetry/api");
|
|
1574
|
+
var INVALID_TRACE_ID = "00000000000000000000000000000000";
|
|
1575
|
+
var INVALID_SPAN_ID = "0000000000000000";
|
|
1576
|
+
function hexToBase64(hex) {
|
|
1577
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
1578
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
1579
|
+
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
1580
|
+
}
|
|
1581
|
+
return base64Encode2(bytes);
|
|
1582
|
+
}
|
|
1583
|
+
function getExplicitTraceContext(traceId, parentSpanId) {
|
|
1584
|
+
if (!traceId || !parentSpanId || !(0, import_api.isValidTraceId)(traceId) || !(0, import_api.isValidSpanId)(parentSpanId)) {
|
|
1585
|
+
return void 0;
|
|
1586
|
+
}
|
|
1587
|
+
return {
|
|
1588
|
+
traceIdB64: hexToBase64(traceId),
|
|
1589
|
+
parentSpanIdB64: hexToBase64(parentSpanId)
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
function getActiveTraceContext() {
|
|
1593
|
+
const activeSpan = import_api.trace.getSpan(import_api.context.active());
|
|
1594
|
+
if (!activeSpan) return {};
|
|
1595
|
+
const spanContext = activeSpan.spanContext();
|
|
1596
|
+
const traceIdHex = spanContext.traceId;
|
|
1597
|
+
const spanIdHex = spanContext.spanId;
|
|
1598
|
+
if (traceIdHex === INVALID_TRACE_ID) return {};
|
|
1599
|
+
return {
|
|
1600
|
+
traceIdB64: hexToBase64(traceIdHex),
|
|
1601
|
+
parentSpanIdB64: spanIdHex !== INVALID_SPAN_ID ? hexToBase64(spanIdHex) : void 0
|
|
1602
|
+
};
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
// src/tracing/multi-project.ts
|
|
1606
|
+
var import_node_crypto = require("crypto");
|
|
1607
|
+
var import_exporter_trace_otlp_proto2 = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
1608
|
+
|
|
1609
|
+
// src/tracing/replay-routing.ts
|
|
1610
|
+
var import_exporter_trace_otlp_proto = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
1611
|
+
var EXPORT_SUCCESS = 0;
|
|
1612
|
+
var EXPORT_FAILED = 1;
|
|
1613
|
+
function recordExportedSpan(destination, span) {
|
|
1614
|
+
if (typeof span !== "object" && typeof span !== "function" || span === null) return;
|
|
1615
|
+
const spanContext = span.spanContext;
|
|
1616
|
+
if (typeof spanContext !== "function") return;
|
|
1617
|
+
const context7 = spanContext.call(span);
|
|
1618
|
+
if (typeof (context7 == null ? void 0 : context7.spanId) === "string" && typeof context7.traceId === "string") {
|
|
1619
|
+
recordReplayExportedSpan(destination, context7.spanId, context7.traceId);
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
function createReplayExporter(destination) {
|
|
1623
|
+
var _a;
|
|
1624
|
+
if (destination.kind === "workshop") {
|
|
1625
|
+
return new import_exporter_trace_otlp_proto.OTLPTraceExporter({
|
|
1626
|
+
url: replayTraceUrl(destination.url)
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
return new import_exporter_trace_otlp_proto.OTLPTraceExporter({
|
|
1630
|
+
url: replayTraceUrl(destination.url),
|
|
1631
|
+
headers: {
|
|
1632
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1633
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1634
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1635
|
+
}
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
var ReplayRoutingSpanExporter = class {
|
|
1639
|
+
constructor(normal, replayExporter = createReplayExporter) {
|
|
1640
|
+
this.normal = normal;
|
|
1641
|
+
this.replayExporter = replayExporter;
|
|
1642
|
+
}
|
|
1643
|
+
export(spans, resultCallback) {
|
|
1644
|
+
const replayGroups = /* @__PURE__ */ new Map();
|
|
1645
|
+
const normalSpans = [];
|
|
1646
|
+
for (const span of spans) {
|
|
1647
|
+
const destination = replayTraceDestinationFor(span);
|
|
1648
|
+
if (!destination) {
|
|
1649
|
+
normalSpans.push(span);
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
const group = replayGroups.get(destination);
|
|
1653
|
+
recordExportedSpan(destination, span);
|
|
1654
|
+
if (group) group.push(span);
|
|
1655
|
+
else replayGroups.set(destination, [span]);
|
|
1656
|
+
}
|
|
1657
|
+
if (replayGroups.size === 0) {
|
|
1658
|
+
this.normal.export(spans, resultCallback);
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
let remaining = replayGroups.size + (normalSpans.length > 0 ? 1 : 0);
|
|
1662
|
+
let failed = false;
|
|
1663
|
+
let firstError;
|
|
1664
|
+
const finish = (result) => {
|
|
1665
|
+
if (result.code !== EXPORT_SUCCESS) {
|
|
1666
|
+
failed = true;
|
|
1667
|
+
firstError != null ? firstError : firstError = result.error;
|
|
1668
|
+
}
|
|
1669
|
+
remaining -= 1;
|
|
1670
|
+
if (remaining === 0) {
|
|
1671
|
+
resultCallback(
|
|
1672
|
+
firstError ? { code: EXPORT_FAILED, error: firstError } : { code: failed ? EXPORT_FAILED : EXPORT_SUCCESS }
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
if (normalSpans.length > 0) {
|
|
1677
|
+
try {
|
|
1678
|
+
this.normal.export(normalSpans, finish);
|
|
1679
|
+
} catch (cause) {
|
|
1680
|
+
finish({
|
|
1681
|
+
code: EXPORT_FAILED,
|
|
1682
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
for (const [destination, replaySpans] of replayGroups) {
|
|
1687
|
+
let exporter;
|
|
1688
|
+
try {
|
|
1689
|
+
exporter = this.replayExporter(destination);
|
|
1690
|
+
} catch (cause) {
|
|
1691
|
+
finish({
|
|
1692
|
+
code: EXPORT_FAILED,
|
|
1693
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1694
|
+
});
|
|
1695
|
+
continue;
|
|
1696
|
+
}
|
|
1697
|
+
try {
|
|
1698
|
+
exporter.export(replaySpans, (result) => {
|
|
1699
|
+
finish(result);
|
|
1700
|
+
void exporter.shutdown().catch(() => {
|
|
1701
|
+
});
|
|
1702
|
+
});
|
|
1703
|
+
} catch (cause) {
|
|
1704
|
+
finish({
|
|
1705
|
+
code: EXPORT_FAILED,
|
|
1706
|
+
error: cause instanceof Error ? cause : new Error(String(cause))
|
|
1707
|
+
});
|
|
1708
|
+
void exporter.shutdown().catch(() => {
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
forceFlush() {
|
|
1714
|
+
return this.normal.forceFlush ? this.normal.forceFlush() : Promise.resolve();
|
|
1715
|
+
}
|
|
1716
|
+
shutdown() {
|
|
1717
|
+
return this.normal.shutdown();
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
|
|
1721
|
+
// src/tracing/multi-project.ts
|
|
1722
|
+
var PROJECT_ID_SPAN_ATTRIBUTE = "raindrop.project_id";
|
|
1723
|
+
var AUTH_HINT_SPAN_ATTRIBUTE = "raindrop.auth_hint";
|
|
1724
|
+
var EXPORT_SUCCESS2 = 0;
|
|
1725
|
+
var EXPORT_FAILED2 = 1;
|
|
1726
|
+
var SPAN_STATUS_ERROR = 2;
|
|
1727
|
+
function authHintForKey(writeKey) {
|
|
1728
|
+
if (!writeKey) return void 0;
|
|
1729
|
+
return (0, import_node_crypto.createHash)("sha256").update(writeKey, "utf8").digest("hex").slice(0, 8);
|
|
1730
|
+
}
|
|
1731
|
+
var STATE_KEY2 = /* @__PURE__ */ Symbol.for("raindrop.tracing.multiProjectState");
|
|
1732
|
+
function getState() {
|
|
1733
|
+
const holder = globalThis;
|
|
1734
|
+
let state2 = holder[STATE_KEY2];
|
|
1735
|
+
if (!state2) {
|
|
1736
|
+
state2 = {
|
|
1737
|
+
foreignClientSeen: false,
|
|
1738
|
+
seenClientHints: /* @__PURE__ */ new Set(),
|
|
1739
|
+
ownerAuthHint: void 0,
|
|
1740
|
+
ownerProjectId: void 0,
|
|
1741
|
+
pipelineClaimed: false,
|
|
1742
|
+
traceloopConfiguredWithoutClaim: false,
|
|
1743
|
+
multiKeyWarned: false,
|
|
1744
|
+
pendingMultiKeyWarning: false
|
|
1745
|
+
};
|
|
1746
|
+
holder[STATE_KEY2] = state2;
|
|
1747
|
+
}
|
|
1748
|
+
return state2;
|
|
1749
|
+
}
|
|
1750
|
+
function emitMultiKeyWarningOnce() {
|
|
1751
|
+
const state2 = getState();
|
|
1752
|
+
if (state2.multiKeyWarned) return;
|
|
1753
|
+
state2.multiKeyWarned = true;
|
|
1754
|
+
state2.pendingMultiKeyWarning = false;
|
|
1755
|
+
console.warn(
|
|
1756
|
+
"[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."
|
|
1757
|
+
);
|
|
1758
|
+
}
|
|
1759
|
+
function registerClientKey(authHint, tracingEnabled = false) {
|
|
1760
|
+
if (!authHint) return;
|
|
1761
|
+
const state2 = getState();
|
|
1762
|
+
state2.seenClientHints.add(authHint);
|
|
1763
|
+
if (state2.seenClientHints.size > 1) {
|
|
1764
|
+
state2.foreignClientSeen = true;
|
|
1765
|
+
if (tracingEnabled || state2.pipelineClaimed) {
|
|
1766
|
+
emitMultiKeyWarningOnce();
|
|
1767
|
+
} else {
|
|
1768
|
+
state2.pendingMultiKeyWarning = true;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
function markForeignClient() {
|
|
1773
|
+
getState().foreignClientSeen = true;
|
|
1774
|
+
}
|
|
1775
|
+
function foreignClientSeen() {
|
|
1776
|
+
return getState().foreignClientSeen;
|
|
1777
|
+
}
|
|
1778
|
+
function stampSpan(span, projectId, authHint) {
|
|
1779
|
+
try {
|
|
1780
|
+
if (projectId) {
|
|
1781
|
+
span.setAttribute(PROJECT_ID_SPAN_ATTRIBUTE, projectId);
|
|
1782
|
+
}
|
|
1783
|
+
if (authHint && foreignClientSeen()) {
|
|
1784
|
+
span.setAttribute(AUTH_HINT_SPAN_ATTRIBUTE, authHint);
|
|
1785
|
+
}
|
|
1786
|
+
} catch (e) {
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
function stampContextAttributes(span) {
|
|
1790
|
+
try {
|
|
1791
|
+
applySpanAttributeFrames(span, (key, value) => span.setAttribute(key, value));
|
|
1792
|
+
for (const [key, value] of Object.entries(evalScopeAttributes())) {
|
|
1793
|
+
span.setAttribute(key, value);
|
|
1794
|
+
}
|
|
1795
|
+
} catch (e) {
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
var RaindropContextSpanProcessor = class {
|
|
1799
|
+
onStart(span) {
|
|
1800
|
+
try {
|
|
1801
|
+
stampContextAttributes(span);
|
|
1802
|
+
rememberReplayTraceDestination(span);
|
|
1803
|
+
const bound = currentRoutingBinding();
|
|
1804
|
+
if (!bound) return;
|
|
1805
|
+
stampSpan(span, bound.projectId, bound.authHint);
|
|
1806
|
+
} catch (e) {
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
onEnd(span) {
|
|
1810
|
+
var _a;
|
|
1811
|
+
try {
|
|
1812
|
+
if (((_a = span == null ? void 0 : span.status) == null ? void 0 : _a.code) !== SPAN_STATUS_ERROR) return;
|
|
1813
|
+
markErrorSpanSeen(span);
|
|
1814
|
+
} catch (e) {
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
async forceFlush() {
|
|
1818
|
+
}
|
|
1819
|
+
async shutdown() {
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
var GuardedSpanExporter = class {
|
|
1823
|
+
constructor(inner, ownerAuthHint) {
|
|
1824
|
+
this.droppedTotal = 0;
|
|
1825
|
+
this.inner = inner;
|
|
1826
|
+
this.ownerAuthHint = ownerAuthHint;
|
|
1827
|
+
}
|
|
1828
|
+
partition(spans) {
|
|
1829
|
+
var _a;
|
|
1830
|
+
const allowed = [];
|
|
1831
|
+
let dropped = 0;
|
|
1832
|
+
const requirePositive = foreignClientSeen();
|
|
1833
|
+
for (const span of spans) {
|
|
1834
|
+
const attrs = (_a = span.attributes) != null ? _a : {};
|
|
1835
|
+
const hint = attrs[AUTH_HINT_SPAN_ATTRIBUTE];
|
|
1836
|
+
const keep = requirePositive ? hint === this.ownerAuthHint : hint === void 0 || hint === this.ownerAuthHint;
|
|
1837
|
+
if (keep) {
|
|
1838
|
+
allowed.push(span);
|
|
1839
|
+
} else {
|
|
1840
|
+
dropped += 1;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
return { allowed, dropped };
|
|
1844
|
+
}
|
|
1845
|
+
warnDropped(dropped) {
|
|
1846
|
+
this.droppedTotal += dropped;
|
|
1847
|
+
const total = this.droppedTotal;
|
|
1848
|
+
rateLimitedLog(
|
|
1849
|
+
"js-sdk.multi-project.dropped",
|
|
1850
|
+
() => console.warn(
|
|
1851
|
+
`[raindrop] Dropped ${dropped} span(s) produced under a different API key than the tracing pipeline's (total dropped: ${total}). One process has ONE OTel pipeline authenticating with the first tracing-enabled client's key; tracing for a different key/org in the same process is unsupported \u2014 run it in its own process. Manual events (track_ai/begin/finish/signals/identify) are unaffected.`
|
|
1852
|
+
)
|
|
1853
|
+
);
|
|
1854
|
+
}
|
|
1855
|
+
export(spans, resultCallback) {
|
|
1856
|
+
let allowed;
|
|
1857
|
+
let dropped;
|
|
1858
|
+
try {
|
|
1859
|
+
({ allowed, dropped } = this.partition(spans));
|
|
1860
|
+
} catch (e) {
|
|
1861
|
+
if (foreignClientSeen()) {
|
|
1862
|
+
this.warnDropped(spans.length);
|
|
1863
|
+
resultCallback({ code: EXPORT_FAILED2 });
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
this.inner.export(spans, resultCallback);
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
if (dropped) {
|
|
1870
|
+
this.warnDropped(dropped);
|
|
1871
|
+
}
|
|
1872
|
+
if (allowed.length === 0) {
|
|
1873
|
+
resultCallback({ code: EXPORT_SUCCESS2 });
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
this.inner.export(allowed, resultCallback);
|
|
1877
|
+
}
|
|
1878
|
+
shutdown() {
|
|
1879
|
+
return this.inner.shutdown();
|
|
1880
|
+
}
|
|
1881
|
+
forceFlush() {
|
|
1882
|
+
return this.inner.forceFlush ? this.inner.forceFlush() : Promise.resolve();
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
function buildGuardedExporter(baseUrl, headers, ownerAuthHint) {
|
|
1886
|
+
const inner = new import_exporter_trace_otlp_proto2.OTLPTraceExporter({
|
|
1887
|
+
url: `${baseUrl}/v1/traces`,
|
|
1888
|
+
headers
|
|
1889
|
+
});
|
|
1890
|
+
return new GuardedSpanExporter(inner, ownerAuthHint);
|
|
1891
|
+
}
|
|
1892
|
+
function pipelineOwnerHint() {
|
|
1893
|
+
return getState().ownerAuthHint;
|
|
1894
|
+
}
|
|
1895
|
+
function claimPipeline(authHint, projectId) {
|
|
1896
|
+
const state2 = getState();
|
|
1897
|
+
if (state2.pipelineClaimed) {
|
|
1898
|
+
return false;
|
|
1899
|
+
}
|
|
1900
|
+
state2.pipelineClaimed = true;
|
|
1901
|
+
state2.ownerAuthHint = authHint;
|
|
1902
|
+
state2.ownerProjectId = projectId;
|
|
1903
|
+
if (state2.foreignClientSeen && state2.pendingMultiKeyWarning) {
|
|
1904
|
+
emitMultiKeyWarningOnce();
|
|
1905
|
+
}
|
|
1906
|
+
return true;
|
|
1907
|
+
}
|
|
1908
|
+
function releasePipelineClaim() {
|
|
1909
|
+
const state2 = getState();
|
|
1910
|
+
state2.pipelineClaimed = false;
|
|
1911
|
+
state2.ownerAuthHint = void 0;
|
|
1912
|
+
state2.ownerProjectId = void 0;
|
|
1913
|
+
}
|
|
1914
|
+
function markTraceloopConfiguredWithoutClaim() {
|
|
1915
|
+
getState().traceloopConfiguredWithoutClaim = true;
|
|
1916
|
+
}
|
|
1917
|
+
function traceloopConfiguredWithoutClaim() {
|
|
1918
|
+
return getState().traceloopConfiguredWithoutClaim;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
// src/tracing/direct/shipper.ts
|
|
1922
|
+
function serializeAssociationValue(value) {
|
|
1923
|
+
return stringifyBounded(value);
|
|
1924
|
+
}
|
|
1925
|
+
var DirectTraceShipper = class {
|
|
1926
|
+
constructor(opts) {
|
|
1927
|
+
this.queue = [];
|
|
1928
|
+
this.inFlight = /* @__PURE__ */ new Set();
|
|
1929
|
+
/**
|
|
1930
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
1931
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
1932
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
1933
|
+
* retry schedule.
|
|
1934
|
+
*/
|
|
1935
|
+
this.hasShutdown = false;
|
|
1936
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1937
|
+
this.writeKey = opts.writeKey;
|
|
1938
|
+
this.baseUrl = (_a = formatEndpoint2(opts.endpoint)) != null ? _a : "https://api.raindrop.ai/v1/";
|
|
1939
|
+
this.enabled = (_b = opts.enabled) != null ? _b : true;
|
|
1940
|
+
this.cloudEnabled = (_c = opts.cloudEnabled) != null ? _c : true;
|
|
1941
|
+
this.debug = opts.debug;
|
|
1942
|
+
this.projectId = opts.projectId;
|
|
1943
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1944
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1945
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1946
|
+
const resolved = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl);
|
|
1947
|
+
if (resolved && resolved !== this.baseUrl) {
|
|
1948
|
+
this.localDebuggerUrl = resolved;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1952
|
+
* Build and enqueue an OTLP span for a trackTool call.
|
|
1953
|
+
*
|
|
1954
|
+
* Reads the active OTEL context if traceId/parentSpanId are not provided,
|
|
1955
|
+
* so spans still appear as children in the trace tree.
|
|
1956
|
+
*/
|
|
1957
|
+
sendSpan(params) {
|
|
1958
|
+
var _a, _b, _c;
|
|
1959
|
+
if (!this.enabled) return;
|
|
1960
|
+
let traceIdB64 = params.traceId;
|
|
1961
|
+
let parentSpanIdB64 = params.parentSpanId;
|
|
1962
|
+
if (!traceIdB64) {
|
|
1963
|
+
const activeCtx = getActiveTraceContext();
|
|
1964
|
+
traceIdB64 = activeCtx.traceIdB64;
|
|
1965
|
+
parentSpanIdB64 = activeCtx.parentSpanIdB64;
|
|
1966
|
+
}
|
|
1967
|
+
const spanIdB64 = (_a = params.spanId) != null ? _a : base64Encode2(randomBytes2(8));
|
|
1968
|
+
if (!traceIdB64) {
|
|
1969
|
+
traceIdB64 = base64Encode2(randomBytes2(16));
|
|
1970
|
+
}
|
|
1971
|
+
const startTimeUnixNano = String(params.startTimeMs * 1e6);
|
|
1972
|
+
const endTimeUnixNano = String(params.endTimeMs * 1e6);
|
|
1973
|
+
const attributes = [
|
|
1974
|
+
// Required: passes hasAIOperation() filter in backend (parseSpan.ts)
|
|
1975
|
+
attrString2("traceloop.span.kind", (_b = params.spanKind) != null ? _b : "tool"),
|
|
1976
|
+
// Parsed by backend for input/output payloads
|
|
1977
|
+
attrString2("traceloop.entity.input", params.input),
|
|
1978
|
+
attrString2("traceloop.entity.output", params.output),
|
|
1979
|
+
// Duration tracking
|
|
1980
|
+
attrInt2("traceloop.entity.duration_ms", params.durationMs),
|
|
1981
|
+
// Per-span project routing: the ingest boundary routes on this attribute
|
|
1982
|
+
// (org-validated) and falls back to the request's project header. Direct
|
|
1983
|
+
// spans ship on this instance's own key, so no cross-key auth hint.
|
|
1984
|
+
attrString2(PROJECT_ID_SPAN_ATTRIBUTE, this.projectId)
|
|
1985
|
+
];
|
|
1986
|
+
for (const [key, value] of Object.entries(params.properties)) {
|
|
1987
|
+
if (value === void 0) {
|
|
1988
|
+
continue;
|
|
1989
|
+
}
|
|
1990
|
+
attributes.push(
|
|
1991
|
+
attrString2(`traceloop.association.properties.${key}`, serializeAssociationValue(value))
|
|
1992
|
+
);
|
|
1993
|
+
}
|
|
1994
|
+
const spanIdentity = { spanIdB64 };
|
|
1995
|
+
claimSpanForFrames(spanIdentity);
|
|
1996
|
+
for (const [key, value] of Object.entries({
|
|
1997
|
+
...currentSpanAttributes(),
|
|
1998
|
+
...params.attributes,
|
|
1999
|
+
// Last, so neither a bound frame nor an explicit caller attribute can
|
|
2000
|
+
// shadow the replay row a span belongs to.
|
|
2001
|
+
...evalScopeAttributes()
|
|
2002
|
+
})) {
|
|
2003
|
+
attributes.push(attrString2(key, value));
|
|
2004
|
+
}
|
|
2005
|
+
attributes.push(...(_c = params.otlpAttributes) != null ? _c : []);
|
|
2006
|
+
let status;
|
|
2007
|
+
if (params.error) {
|
|
2008
|
+
status = { code: 2, message: params.error };
|
|
2009
|
+
markErrorSpanSeen(spanIdentity);
|
|
2010
|
+
} else {
|
|
2011
|
+
status = {
|
|
2012
|
+
code: 1
|
|
2013
|
+
/* STATUS_CODE_OK */
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
const span = buildOtlpSpan2({
|
|
2017
|
+
ids: {
|
|
2018
|
+
traceIdB64,
|
|
2019
|
+
spanIdB64,
|
|
2020
|
+
parentSpanIdB64
|
|
2021
|
+
},
|
|
2022
|
+
name: params.name,
|
|
2023
|
+
startTimeUnixNano,
|
|
2024
|
+
endTimeUnixNano,
|
|
2025
|
+
attributes,
|
|
2026
|
+
status
|
|
2027
|
+
});
|
|
2028
|
+
const replayDestination = currentReplayTraceDestination();
|
|
2029
|
+
recordReplayExportedSpan(
|
|
2030
|
+
replayDestination,
|
|
2031
|
+
base64ToHex2(span.spanId),
|
|
2032
|
+
base64ToHex2(span.traceId)
|
|
2033
|
+
);
|
|
2034
|
+
const mirrorUrl = (replayDestination == null ? void 0 : replayDestination.kind) === "workshop" ? replayDestination.url : replayDestination ? void 0 : this.localDebuggerUrl;
|
|
2035
|
+
if (mirrorUrl) {
|
|
2036
|
+
const body = buildExportTraceServiceRequest2([span]);
|
|
2037
|
+
const mirror = mirrorTraceExportToLocalDebugger(body, {
|
|
2038
|
+
baseUrl: mirrorUrl,
|
|
2039
|
+
debug: false,
|
|
2040
|
+
sdkName: "js-sdk"
|
|
2041
|
+
});
|
|
2042
|
+
this.inFlight.add(mirror);
|
|
2043
|
+
void mirror.finally(() => this.inFlight.delete(mirror));
|
|
2044
|
+
}
|
|
2045
|
+
this.enqueue({ span, replayDestination });
|
|
2046
|
+
if (this.debug) {
|
|
2047
|
+
console.log(`[raindrop] direct shipper: enqueued span "${params.name}"`);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
sendToolSpan(params) {
|
|
2051
|
+
this.sendSpan({
|
|
2052
|
+
...params,
|
|
2053
|
+
spanKind: "tool"
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2056
|
+
enqueue(queued) {
|
|
2057
|
+
if (!this.enabled) return;
|
|
2058
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
2059
|
+
this.queue.shift();
|
|
2060
|
+
}
|
|
2061
|
+
this.queue.push(queued);
|
|
2062
|
+
if (this.queue.length >= this.maxBatchSize) {
|
|
2063
|
+
void this.flush().catch(() => {
|
|
2064
|
+
});
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
if (!this.timer) {
|
|
2068
|
+
this.timer = setTimeout(() => {
|
|
2069
|
+
this.timer = void 0;
|
|
2070
|
+
void this.flush().catch(() => {
|
|
2071
|
+
});
|
|
2072
|
+
}, this.flushIntervalMs);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
async flush() {
|
|
2076
|
+
var _a;
|
|
2077
|
+
if (!this.enabled) return;
|
|
2078
|
+
if (this.timer) {
|
|
2079
|
+
clearTimeout(this.timer);
|
|
2080
|
+
this.timer = void 0;
|
|
2081
|
+
}
|
|
2082
|
+
while (this.queue.length > 0) {
|
|
2083
|
+
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
2084
|
+
const opts = this.requestOpts();
|
|
2085
|
+
if (!opts) {
|
|
2086
|
+
rateLimitedLog(
|
|
2087
|
+
"js-sdk.direct.shutdown_deadline",
|
|
2088
|
+
() => console.warn(
|
|
2089
|
+
`[raindrop] direct: shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
2090
|
+
)
|
|
2091
|
+
);
|
|
2092
|
+
continue;
|
|
2093
|
+
}
|
|
2094
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2095
|
+
for (const queued of batch) {
|
|
2096
|
+
const spans = groups.get(queued.replayDestination);
|
|
2097
|
+
if (spans) spans.push(queued.span);
|
|
2098
|
+
else groups.set(queued.replayDestination, [queued.span]);
|
|
2099
|
+
}
|
|
2100
|
+
for (const [replayDestination, spans] of groups) {
|
|
2101
|
+
if (!replayDestination && !this.cloudEnabled) continue;
|
|
2102
|
+
if ((replayDestination == null ? void 0 : replayDestination.kind) === "workshop") continue;
|
|
2103
|
+
const body = buildExportTraceServiceRequest2(spans);
|
|
2104
|
+
const url = replayDestination ? replayTraceUrl(replayDestination.url) : `${this.baseUrl}traces`;
|
|
2105
|
+
const headers = replayDestination ? {
|
|
2106
|
+
Authorization: `Bearer ${replayDestination.apiKey}`,
|
|
2107
|
+
"X-Raindrop-Replay-Id": replayDestination.replayId,
|
|
2108
|
+
"X-Raindrop-Project-Id": (_a = replayDestination.projectId) != null ? _a : "default"
|
|
2109
|
+
} : { Authorization: `Bearer ${this.writeKey}`, ...projectIdHeaders(this.projectId) };
|
|
2110
|
+
const p = postJson2(url, body, headers, opts);
|
|
2111
|
+
this.inFlight.add(p);
|
|
2112
|
+
try {
|
|
2113
|
+
try {
|
|
2114
|
+
await p;
|
|
2115
|
+
if (this.debug) console.log(`[raindrop] direct: sent ${spans.length} spans`);
|
|
2116
|
+
} catch (err) {
|
|
2117
|
+
if (this.debug) {
|
|
2118
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2119
|
+
console.warn(`[raindrop] direct: failed to send spans (dropping): ${msg}`);
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
} finally {
|
|
2123
|
+
this.inFlight.delete(p);
|
|
2124
|
+
}
|
|
1835
2125
|
}
|
|
1836
|
-
|
|
1837
|
-
};
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
// src/tracing/direct/context.ts
|
|
1841
|
-
var import_api2 = require("@opentelemetry/api");
|
|
1842
|
-
var INVALID_TRACE_ID = "00000000000000000000000000000000";
|
|
1843
|
-
var INVALID_SPAN_ID = "0000000000000000";
|
|
1844
|
-
function hexToBase64(hex) {
|
|
1845
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
1846
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
1847
|
-
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
2126
|
+
}
|
|
1848
2127
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
2128
|
+
/**
|
|
2129
|
+
* Retry/timeout options for one batch POST, honoring the shutdown budget:
|
|
2130
|
+
* outside shutdown, the normal 3-attempt schedule; during shutdown, a
|
|
2131
|
+
* single attempt clamped to the remaining window; `null` once the window
|
|
2132
|
+
* is exhausted (caller drops the batch). After shutdown() returns,
|
|
2133
|
+
* stragglers run as a single short attempt.
|
|
2134
|
+
*/
|
|
2135
|
+
requestOpts() {
|
|
2136
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
2137
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
2138
|
+
if (remainingMs <= 0) return null;
|
|
2139
|
+
return {
|
|
2140
|
+
maxAttempts: 1,
|
|
2141
|
+
debug: this.debug,
|
|
2142
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
if (this.hasShutdown) {
|
|
2146
|
+
return { maxAttempts: 1, debug: this.debug, timeoutMs: POST_SHUTDOWN_TIMEOUT_MS };
|
|
2147
|
+
}
|
|
2148
|
+
return { maxAttempts: 3, debug: this.debug };
|
|
1854
2149
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
}
|
|
2150
|
+
async shutdown() {
|
|
2151
|
+
this.hasShutdown = true;
|
|
2152
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
2153
|
+
try {
|
|
2154
|
+
if (this.timer) {
|
|
2155
|
+
clearTimeout(this.timer);
|
|
2156
|
+
this.timer = void 0;
|
|
2157
|
+
}
|
|
2158
|
+
const drain = async () => {
|
|
2159
|
+
await this.flush();
|
|
2160
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
2161
|
+
})));
|
|
2162
|
+
};
|
|
2163
|
+
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
2164
|
+
if (!settled && this.debug) {
|
|
2165
|
+
console.warn("[raindrop] direct: shutdown deadline exceeded; abandoning in-flight spans");
|
|
2166
|
+
}
|
|
2167
|
+
} finally {
|
|
2168
|
+
this.shutdownDeadlineAt = void 0;
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
1872
2172
|
|
|
1873
|
-
// src/tracing/
|
|
1874
|
-
var
|
|
1875
|
-
var
|
|
1876
|
-
var
|
|
1877
|
-
var
|
|
1878
|
-
var
|
|
1879
|
-
var
|
|
1880
|
-
var
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
var
|
|
2173
|
+
// src/tracing/otel-core/index.ts
|
|
2174
|
+
var import_api2 = require("@opentelemetry/api");
|
|
2175
|
+
var import_core6 = require("@opentelemetry/core");
|
|
2176
|
+
var import_exporter_trace_otlp_proto3 = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
2177
|
+
var import_instrumentation = require("@opentelemetry/instrumentation");
|
|
2178
|
+
var resourceModule = __toESM(require("@opentelemetry/resources"));
|
|
2179
|
+
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
2180
|
+
var import_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
|
|
2181
|
+
var import_ai_semantic_conventions = require("@traceloop/ai-semantic-conventions");
|
|
2182
|
+
var ALL_INSTRUMENTATION_LIBRARIES = "all";
|
|
2183
|
+
var TRACER_NAME = "@traceloop/node-server-sdk";
|
|
2184
|
+
var WORKFLOW_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.workflowName");
|
|
2185
|
+
var ENTITY_NAME_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.entityName");
|
|
2186
|
+
var ASSOCIATION_PROPERTIES_KEY = /* @__PURE__ */ Symbol.for("raindrop.otelCore.associationProperties");
|
|
2187
|
+
var INSTRUMENTATION_LIBRARIES = [
|
|
2188
|
+
"ai",
|
|
2189
|
+
"@traceloop/node-server-sdk",
|
|
2190
|
+
"@traceloop/instrumentation-openai",
|
|
2191
|
+
"@traceloop/instrumentation-langchain",
|
|
2192
|
+
"@traceloop/instrumentation-chroma",
|
|
2193
|
+
"@traceloop/instrumentation-chromadb",
|
|
2194
|
+
"@traceloop/instrumentation-anthropic",
|
|
2195
|
+
"@traceloop/instrumentation-llamaindex",
|
|
2196
|
+
"@traceloop/instrumentation-vertexai",
|
|
2197
|
+
"@traceloop/instrumentation-bedrock",
|
|
2198
|
+
"@traceloop/instrumentation-cohere",
|
|
2199
|
+
"@traceloop/instrumentation-pinecone",
|
|
2200
|
+
"@traceloop/instrumentation-qdrant",
|
|
2201
|
+
"@traceloop/instrumentation-together",
|
|
2202
|
+
TRACER_NAME,
|
|
2203
|
+
"traceloop.tracer"
|
|
2204
|
+
];
|
|
2205
|
+
var AI_GENERATE_TEXT = "ai.generateText.doGenerate";
|
|
2206
|
+
var AI_STREAM_TEXT = "ai.streamText.doStream";
|
|
2207
|
+
var AI_RESPONSE_TEXT = "ai.response.text";
|
|
2208
|
+
var AI_PROMPT_MESSAGES = "ai.prompt.messages";
|
|
2209
|
+
var AI_PROMPT_TOKENS = "ai.usage.promptTokens";
|
|
2210
|
+
var AI_COMPLETION_TOKENS = "ai.usage.completionTokens";
|
|
2211
|
+
var AI_MODEL_PROVIDER = "ai.model.provider";
|
|
2212
|
+
var STATE_KEY3 = /* @__PURE__ */ Symbol.for("raindrop.otelCore.state");
|
|
1886
2213
|
function getState2() {
|
|
2214
|
+
var _a;
|
|
1887
2215
|
const holder = globalThis;
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
state = {
|
|
1891
|
-
foreignClientSeen: false,
|
|
1892
|
-
seenClientHints: /* @__PURE__ */ new Set(),
|
|
1893
|
-
ownerAuthHint: void 0,
|
|
1894
|
-
ownerProjectId: void 0,
|
|
1895
|
-
pipelineClaimed: false,
|
|
1896
|
-
traceloopConfiguredWithoutClaim: false,
|
|
1897
|
-
multiKeyWarned: false,
|
|
1898
|
-
pendingMultiKeyWarning: false
|
|
1899
|
-
};
|
|
1900
|
-
holder[STATE_KEY2] = state;
|
|
1901
|
-
}
|
|
1902
|
-
return state;
|
|
2216
|
+
(_a = holder[STATE_KEY3]) != null ? _a : holder[STATE_KEY3] = {};
|
|
2217
|
+
return holder[STATE_KEY3];
|
|
1903
2218
|
}
|
|
1904
|
-
function
|
|
1905
|
-
const
|
|
1906
|
-
if (
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
const state = getState2();
|
|
1916
|
-
state.seenClientHints.add(authHint);
|
|
1917
|
-
if (state.seenClientHints.size > 1) {
|
|
1918
|
-
state.foreignClientSeen = true;
|
|
1919
|
-
if (tracingEnabled || state.pipelineClaimed) {
|
|
1920
|
-
emitMultiKeyWarningOnce();
|
|
1921
|
-
} else {
|
|
1922
|
-
state.pendingMultiKeyWarning = true;
|
|
2219
|
+
function parseHeaders(value) {
|
|
2220
|
+
const headers = {};
|
|
2221
|
+
if (!value) return headers;
|
|
2222
|
+
for (const pair of value.split(",")) {
|
|
2223
|
+
const separator = pair.indexOf("=");
|
|
2224
|
+
if (separator <= 0) continue;
|
|
2225
|
+
try {
|
|
2226
|
+
const key = decodeURIComponent(pair.slice(0, separator).trim());
|
|
2227
|
+
const val = decodeURIComponent(pair.slice(separator + 1).trim());
|
|
2228
|
+
if (key && val) headers[key] = val;
|
|
2229
|
+
} catch (e) {
|
|
1923
2230
|
}
|
|
1924
2231
|
}
|
|
2232
|
+
return headers;
|
|
1925
2233
|
}
|
|
1926
|
-
function
|
|
1927
|
-
getState2().foreignClientSeen = true;
|
|
1928
|
-
}
|
|
1929
|
-
function foreignClientSeen() {
|
|
1930
|
-
return getState2().foreignClientSeen;
|
|
1931
|
-
}
|
|
1932
|
-
function stampSpan(span, projectId, authHint) {
|
|
2234
|
+
function safeStringify(value) {
|
|
1933
2235
|
try {
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
}
|
|
1937
|
-
if (authHint && foreignClientSeen()) {
|
|
1938
|
-
span.setAttribute(AUTH_HINT_SPAN_ATTRIBUTE, authHint);
|
|
1939
|
-
}
|
|
2236
|
+
const result = JSON.stringify(value);
|
|
2237
|
+
return result === void 0 ? String(value) : result;
|
|
1940
2238
|
} catch (e) {
|
|
2239
|
+
return "[unserializable]";
|
|
1941
2240
|
}
|
|
1942
2241
|
}
|
|
1943
|
-
function
|
|
2242
|
+
function createResource(attributes) {
|
|
2243
|
+
if ("resourceFromAttributes" in resourceModule) {
|
|
2244
|
+
const factory = resourceModule.resourceFromAttributes;
|
|
2245
|
+
if (typeof factory === "function") return factory(attributes);
|
|
2246
|
+
}
|
|
2247
|
+
return new resourceModule.Resource(attributes);
|
|
2248
|
+
}
|
|
2249
|
+
function detectRuntimeResource() {
|
|
1944
2250
|
try {
|
|
1945
|
-
|
|
2251
|
+
if ("detectResourcesSync" in resourceModule && typeof resourceModule.detectResourcesSync === "function" && "envDetectorSync" in resourceModule) {
|
|
2252
|
+
return resourceModule.detectResourcesSync({
|
|
2253
|
+
detectors: [
|
|
2254
|
+
resourceModule.envDetectorSync,
|
|
2255
|
+
resourceModule.processDetectorSync,
|
|
2256
|
+
resourceModule.hostDetectorSync
|
|
2257
|
+
]
|
|
2258
|
+
});
|
|
2259
|
+
}
|
|
2260
|
+
if ("detectResources" in resourceModule && typeof resourceModule.detectResources === "function" && "envDetector" in resourceModule) {
|
|
2261
|
+
const detected = resourceModule.detectResources({
|
|
2262
|
+
detectors: [
|
|
2263
|
+
resourceModule.envDetector,
|
|
2264
|
+
resourceModule.processDetector,
|
|
2265
|
+
resourceModule.hostDetector
|
|
2266
|
+
]
|
|
2267
|
+
});
|
|
2268
|
+
if (!(detected instanceof Promise)) {
|
|
2269
|
+
return detected;
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
1946
2272
|
} catch (e) {
|
|
1947
2273
|
}
|
|
2274
|
+
return void 0;
|
|
1948
2275
|
}
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2276
|
+
function logLevel(level) {
|
|
2277
|
+
switch (level) {
|
|
2278
|
+
case "debug":
|
|
2279
|
+
return import_api2.DiagLogLevel.DEBUG;
|
|
2280
|
+
case "info":
|
|
2281
|
+
return import_api2.DiagLogLevel.INFO;
|
|
2282
|
+
case "warn":
|
|
2283
|
+
return import_api2.DiagLogLevel.WARN;
|
|
2284
|
+
default:
|
|
2285
|
+
return import_api2.DiagLogLevel.ERROR;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
function transformAiSdkSpan(span) {
|
|
2289
|
+
const names = {
|
|
2290
|
+
[AI_GENERATE_TEXT]: "ai.generateText.generate",
|
|
2291
|
+
[AI_STREAM_TEXT]: "ai.streamText.stream"
|
|
2292
|
+
};
|
|
2293
|
+
if (!(span.name in names)) return span;
|
|
2294
|
+
const attributes = span.attributes;
|
|
2295
|
+
if (AI_RESPONSE_TEXT in attributes) {
|
|
2296
|
+
const response = attributes[AI_RESPONSE_TEXT];
|
|
2297
|
+
if (typeof response === "string") {
|
|
2298
|
+
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_COMPLETIONS}.0.content`] = response;
|
|
1957
2299
|
}
|
|
2300
|
+
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_COMPLETIONS}.0.role`] = "assistant";
|
|
2301
|
+
delete attributes[AI_RESPONSE_TEXT];
|
|
1958
2302
|
}
|
|
1959
|
-
|
|
1960
|
-
var _a;
|
|
2303
|
+
if (AI_PROMPT_MESSAGES in attributes) {
|
|
1961
2304
|
try {
|
|
1962
|
-
|
|
1963
|
-
|
|
2305
|
+
const parsed = JSON.parse(String(attributes[AI_PROMPT_MESSAGES]));
|
|
2306
|
+
if (Array.isArray(parsed)) {
|
|
2307
|
+
parsed.forEach((message, index) => {
|
|
2308
|
+
if (!message || typeof message !== "object") return;
|
|
2309
|
+
const content = "content" in message ? message.content : void 0;
|
|
2310
|
+
const role = "role" in message ? message.role : void 0;
|
|
2311
|
+
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.content`] = typeof content === "string" ? content : safeStringify(content);
|
|
2312
|
+
if (typeof role === "string") {
|
|
2313
|
+
attributes[`${import_ai_semantic_conventions.SpanAttributes.LLM_PROMPTS}.${index}.role`] = role;
|
|
2314
|
+
}
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
delete attributes[AI_PROMPT_MESSAGES];
|
|
1964
2318
|
} catch (e) {
|
|
1965
2319
|
}
|
|
1966
2320
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
}
|
|
1971
|
-
};
|
|
1972
|
-
var GuardedSpanExporter = class {
|
|
1973
|
-
constructor(inner, ownerAuthHint) {
|
|
1974
|
-
this.droppedTotal = 0;
|
|
1975
|
-
this.inner = inner;
|
|
1976
|
-
this.ownerAuthHint = ownerAuthHint;
|
|
1977
|
-
}
|
|
1978
|
-
partition(spans) {
|
|
1979
|
-
var _a;
|
|
1980
|
-
const allowed = [];
|
|
1981
|
-
let dropped = 0;
|
|
1982
|
-
const requirePositive = foreignClientSeen();
|
|
1983
|
-
for (const span of spans) {
|
|
1984
|
-
const attrs = (_a = span.attributes) != null ? _a : {};
|
|
1985
|
-
const hint = attrs[AUTH_HINT_SPAN_ATTRIBUTE];
|
|
1986
|
-
const keep = requirePositive ? hint === this.ownerAuthHint : hint === void 0 || hint === this.ownerAuthHint;
|
|
1987
|
-
if (keep) {
|
|
1988
|
-
allowed.push(span);
|
|
1989
|
-
} else {
|
|
1990
|
-
dropped += 1;
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
return { allowed, dropped };
|
|
2321
|
+
if (AI_PROMPT_TOKENS in attributes) {
|
|
2322
|
+
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS] = Number(attributes[AI_PROMPT_TOKENS]);
|
|
2323
|
+
delete attributes[AI_PROMPT_TOKENS];
|
|
1994
2324
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
rateLimitedLog(
|
|
1999
|
-
"js-sdk.multi-project.dropped",
|
|
2000
|
-
() => console.warn(
|
|
2001
|
-
`[raindrop] Dropped ${dropped} span(s) produced under a different API key than the tracing pipeline's (total dropped: ${total}). One process has ONE OTel pipeline authenticating with the first tracing-enabled client's key; tracing for a different key/org in the same process is unsupported \u2014 run it in its own process. Manual events (track_ai/begin/finish/signals/identify) are unaffected.`
|
|
2002
|
-
)
|
|
2325
|
+
if (AI_COMPLETION_TOKENS in attributes) {
|
|
2326
|
+
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] = Number(
|
|
2327
|
+
attributes[AI_COMPLETION_TOKENS]
|
|
2003
2328
|
);
|
|
2329
|
+
delete attributes[AI_COMPLETION_TOKENS];
|
|
2004
2330
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
({ allowed, dropped } = this.partition(spans));
|
|
2010
|
-
} catch (e) {
|
|
2011
|
-
if (foreignClientSeen()) {
|
|
2012
|
-
this.warnDropped(spans.length);
|
|
2013
|
-
resultCallback({ code: EXPORT_FAILED });
|
|
2014
|
-
return;
|
|
2015
|
-
}
|
|
2016
|
-
this.inner.export(spans, resultCallback);
|
|
2017
|
-
return;
|
|
2018
|
-
}
|
|
2019
|
-
if (dropped) {
|
|
2020
|
-
this.warnDropped(dropped);
|
|
2021
|
-
}
|
|
2022
|
-
if (allowed.length === 0) {
|
|
2023
|
-
resultCallback({ code: EXPORT_SUCCESS });
|
|
2024
|
-
return;
|
|
2025
|
-
}
|
|
2026
|
-
this.inner.export(allowed, resultCallback);
|
|
2027
|
-
}
|
|
2028
|
-
shutdown() {
|
|
2029
|
-
return this.inner.shutdown();
|
|
2331
|
+
const prompt = attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_PROMPT_TOKENS];
|
|
2332
|
+
const completion = attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_COMPLETION_TOKENS];
|
|
2333
|
+
if (prompt !== void 0 && completion !== void 0) {
|
|
2334
|
+
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_USAGE_TOTAL_TOKENS] = Number(prompt) + Number(completion);
|
|
2030
2335
|
}
|
|
2031
|
-
|
|
2032
|
-
|
|
2336
|
+
if (AI_MODEL_PROVIDER in attributes) {
|
|
2337
|
+
const vendor = String(attributes[AI_MODEL_PROVIDER]);
|
|
2338
|
+
attributes[import_ai_semantic_conventions.SpanAttributes.LLM_SYSTEM] = vendor.startsWith("openai") ? "OpenAI" : vendor;
|
|
2339
|
+
delete attributes[AI_MODEL_PROVIDER];
|
|
2033
2340
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
headers
|
|
2341
|
+
Object.defineProperty(span, "name", {
|
|
2342
|
+
configurable: true,
|
|
2343
|
+
value: names[span.name],
|
|
2344
|
+
writable: true
|
|
2039
2345
|
});
|
|
2040
|
-
return
|
|
2041
|
-
}
|
|
2042
|
-
function pipelineOwnerHint() {
|
|
2043
|
-
return getState2().ownerAuthHint;
|
|
2346
|
+
return span;
|
|
2044
2347
|
}
|
|
2045
|
-
function
|
|
2046
|
-
|
|
2047
|
-
if (
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
state.ownerProjectId = projectId;
|
|
2053
|
-
if (state.foreignClientSeen && state.pendingMultiKeyWarning) {
|
|
2054
|
-
emitMultiKeyWarningOnce();
|
|
2348
|
+
function scopeName(span) {
|
|
2349
|
+
var _a;
|
|
2350
|
+
if ("instrumentationScope" in span) {
|
|
2351
|
+
const scope = span.instrumentationScope;
|
|
2352
|
+
if (scope && typeof scope === "object" && "name" in scope && typeof scope.name === "string") {
|
|
2353
|
+
return scope.name;
|
|
2354
|
+
}
|
|
2055
2355
|
}
|
|
2056
|
-
return
|
|
2057
|
-
}
|
|
2058
|
-
function releasePipelineClaim() {
|
|
2059
|
-
const state = getState2();
|
|
2060
|
-
state.pipelineClaimed = false;
|
|
2061
|
-
state.ownerAuthHint = void 0;
|
|
2062
|
-
state.ownerProjectId = void 0;
|
|
2063
|
-
}
|
|
2064
|
-
function markTraceloopConfiguredWithoutClaim() {
|
|
2065
|
-
getState2().traceloopConfiguredWithoutClaim = true;
|
|
2066
|
-
}
|
|
2067
|
-
function traceloopConfiguredWithoutClaim() {
|
|
2068
|
-
return getState2().traceloopConfiguredWithoutClaim;
|
|
2356
|
+
return (_a = span.instrumentationLibrary) == null ? void 0 : _a.name;
|
|
2069
2357
|
}
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
function serializeAssociationValue(value) {
|
|
2073
|
-
return stringifyBounded(value);
|
|
2358
|
+
function contentCaptureDisabled(options) {
|
|
2359
|
+
return options.traceContent === false || (process.env.TRACELOOP_TRACE_CONTENT || "true").toLowerCase() === "false";
|
|
2074
2360
|
}
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
2096
|
-
const resolved = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl);
|
|
2097
|
-
if (resolved && resolved !== this.baseUrl) {
|
|
2098
|
-
this.localDebuggerUrl = resolved;
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
/**
|
|
2102
|
-
* Build and enqueue an OTLP span for a trackTool call.
|
|
2103
|
-
*
|
|
2104
|
-
* Reads the active OTEL context if traceId/parentSpanId are not provided,
|
|
2105
|
-
* so spans still appear as children in the trace tree.
|
|
2106
|
-
*/
|
|
2107
|
-
sendSpan(params) {
|
|
2108
|
-
var _a, _b, _c;
|
|
2109
|
-
if (!this.enabled) return;
|
|
2110
|
-
let traceIdB64 = params.traceId;
|
|
2111
|
-
let parentSpanIdB64 = params.parentSpanId;
|
|
2112
|
-
if (!traceIdB64) {
|
|
2113
|
-
const activeCtx = getActiveTraceContext();
|
|
2114
|
-
traceIdB64 = activeCtx.traceIdB64;
|
|
2115
|
-
parentSpanIdB64 = activeCtx.parentSpanIdB64;
|
|
2116
|
-
}
|
|
2117
|
-
const spanIdB64 = (_a = params.spanId) != null ? _a : base64Encode2(randomBytes2(8));
|
|
2118
|
-
if (!traceIdB64) {
|
|
2119
|
-
traceIdB64 = base64Encode2(randomBytes2(16));
|
|
2120
|
-
}
|
|
2121
|
-
const startTimeUnixNano = String(params.startTimeMs * 1e6);
|
|
2122
|
-
const endTimeUnixNano = String(params.endTimeMs * 1e6);
|
|
2123
|
-
const attributes = [
|
|
2124
|
-
// Required: passes hasAIOperation() filter in backend (parseSpan.ts)
|
|
2125
|
-
attrString2("traceloop.span.kind", (_b = params.spanKind) != null ? _b : "tool"),
|
|
2126
|
-
// Parsed by backend for input/output payloads
|
|
2127
|
-
attrString2("traceloop.entity.input", params.input),
|
|
2128
|
-
attrString2("traceloop.entity.output", params.output),
|
|
2129
|
-
// Duration tracking
|
|
2130
|
-
attrInt2("traceloop.entity.duration_ms", params.durationMs),
|
|
2131
|
-
// Per-span project routing: the ingest boundary routes on this attribute
|
|
2132
|
-
// (org-validated) and falls back to the request's project header. Direct
|
|
2133
|
-
// spans ship on this instance's own key, so no cross-key auth hint.
|
|
2134
|
-
attrString2(PROJECT_ID_SPAN_ATTRIBUTE, this.projectId)
|
|
2135
|
-
];
|
|
2136
|
-
for (const [key, value] of Object.entries(params.properties)) {
|
|
2137
|
-
if (value === void 0) {
|
|
2138
|
-
continue;
|
|
2139
|
-
}
|
|
2140
|
-
attributes.push(
|
|
2141
|
-
attrString2(`traceloop.association.properties.${key}`, serializeAssociationValue(value))
|
|
2142
|
-
);
|
|
2143
|
-
}
|
|
2144
|
-
const spanIdentity = { spanIdB64 };
|
|
2145
|
-
claimSpanForFrames(spanIdentity);
|
|
2146
|
-
for (const [key, value] of Object.entries({
|
|
2147
|
-
...currentSpanAttributes(),
|
|
2148
|
-
...params.attributes
|
|
2149
|
-
})) {
|
|
2150
|
-
attributes.push(attrString2(key, value));
|
|
2151
|
-
}
|
|
2152
|
-
attributes.push(...(_c = params.otlpAttributes) != null ? _c : []);
|
|
2153
|
-
let status;
|
|
2154
|
-
if (params.error) {
|
|
2155
|
-
status = { code: 2, message: params.error };
|
|
2156
|
-
markErrorSpanSeen(spanIdentity);
|
|
2157
|
-
} else {
|
|
2158
|
-
status = {
|
|
2159
|
-
code: 1
|
|
2160
|
-
/* STATUS_CODE_OK */
|
|
2161
|
-
};
|
|
2162
|
-
}
|
|
2163
|
-
const span = buildOtlpSpan2({
|
|
2164
|
-
ids: {
|
|
2165
|
-
traceIdB64,
|
|
2166
|
-
spanIdB64,
|
|
2167
|
-
parentSpanIdB64
|
|
2168
|
-
},
|
|
2169
|
-
name: params.name,
|
|
2170
|
-
startTimeUnixNano,
|
|
2171
|
-
endTimeUnixNano,
|
|
2172
|
-
attributes,
|
|
2173
|
-
status
|
|
2174
|
-
});
|
|
2175
|
-
if (this.localDebuggerUrl) {
|
|
2176
|
-
const body = buildExportTraceServiceRequest2([span]);
|
|
2177
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
2178
|
-
baseUrl: this.localDebuggerUrl,
|
|
2179
|
-
debug: false,
|
|
2180
|
-
sdkName: "js-sdk"
|
|
2181
|
-
});
|
|
2182
|
-
}
|
|
2183
|
-
this.enqueue(span);
|
|
2184
|
-
if (this.debug) {
|
|
2185
|
-
console.log(`[raindrop] direct shipper: enqueued span "${params.name}"`);
|
|
2361
|
+
function shouldSendTraceContent() {
|
|
2362
|
+
var _a;
|
|
2363
|
+
const contextual = import_api2.context.active().getValue(import_ai_semantic_conventions.CONTEXT_KEY_ALLOW_TRACE_CONTENT);
|
|
2364
|
+
if (typeof contextual === "boolean") return contextual;
|
|
2365
|
+
if (((_a = getState2().configuration) == null ? void 0 : _a.traceContent) === false) return false;
|
|
2366
|
+
return (process.env.TRACELOOP_TRACE_CONTENT || "true").toLowerCase() !== "false";
|
|
2367
|
+
}
|
|
2368
|
+
function enrichStart(span) {
|
|
2369
|
+
const active = import_api2.context.active();
|
|
2370
|
+
const workflow = active.getValue(WORKFLOW_NAME_KEY);
|
|
2371
|
+
if (typeof workflow === "string")
|
|
2372
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_WORKFLOW_NAME, workflow);
|
|
2373
|
+
const entity = active.getValue(ENTITY_NAME_KEY);
|
|
2374
|
+
if (typeof entity === "string") span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_PATH, entity);
|
|
2375
|
+
const properties = active.getValue(ASSOCIATION_PROPERTIES_KEY);
|
|
2376
|
+
if (properties && typeof properties === "object") {
|
|
2377
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
2378
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
2379
|
+
span.setAttribute(`${import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.${key}`, value);
|
|
2380
|
+
}
|
|
2186
2381
|
}
|
|
2187
2382
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2383
|
+
}
|
|
2384
|
+
function createSpanProcessor(options) {
|
|
2385
|
+
var _a, _b;
|
|
2386
|
+
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
2387
|
+
const apiKey = options.apiKey || process.env.TRACELOOP_API_KEY;
|
|
2388
|
+
const resolvedHeaders = (_a = options.headers) != null ? _a : process.env.TRACELOOP_HEADERS ? parseHeaders(process.env.TRACELOOP_HEADERS) : { Authorization: `Bearer ${apiKey}` };
|
|
2389
|
+
const baseExporter = (_b = options.exporter) != null ? _b : new import_exporter_trace_otlp_proto3.OTLPTraceExporter({ url: `${baseUrl}/v1/traces`, headers: resolvedHeaders });
|
|
2390
|
+
const exporter = options.routeReplayTraces ? new ReplayRoutingSpanExporter(baseExporter) : baseExporter;
|
|
2391
|
+
const processor = options.disableBatch ? new import_sdk_trace_base.SimpleSpanProcessor(exporter) : new import_sdk_trace_base.BatchSpanProcessor(exporter);
|
|
2392
|
+
const originalOnStart = processor.onStart.bind(processor);
|
|
2393
|
+
const originalOnEnd = processor.onEnd.bind(processor);
|
|
2394
|
+
processor.onStart = (span, parentContext) => {
|
|
2395
|
+
try {
|
|
2396
|
+
enrichStart(span);
|
|
2397
|
+
originalOnStart(span, parentContext);
|
|
2398
|
+
} catch (e) {
|
|
2198
2399
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2400
|
+
};
|
|
2401
|
+
processor.onEnd = (span) => {
|
|
2402
|
+
var _a2;
|
|
2403
|
+
let outgoing = span;
|
|
2404
|
+
try {
|
|
2405
|
+
const allowed = options.allowedInstrumentationLibraries;
|
|
2406
|
+
if (allowed !== ALL_INSTRUMENTATION_LIBRARIES && ![...INSTRUMENTATION_LIBRARIES, ...allowed != null ? allowed : []].includes((_a2 = scopeName(span)) != null ? _a2 : "")) {
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
outgoing = transformAiSdkSpan(span);
|
|
2410
|
+
if (outgoing !== span) copyReplayTraceDestination(span, outgoing);
|
|
2411
|
+
} catch (e) {
|
|
2204
2412
|
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
void this.flush().catch(() => {
|
|
2209
|
-
});
|
|
2210
|
-
}, this.flushIntervalMs);
|
|
2413
|
+
try {
|
|
2414
|
+
originalOnEnd(outgoing);
|
|
2415
|
+
} catch (e) {
|
|
2211
2416
|
}
|
|
2212
|
-
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2417
|
+
};
|
|
2418
|
+
return processor;
|
|
2419
|
+
}
|
|
2420
|
+
function initialize(options = {}) {
|
|
2421
|
+
var _a;
|
|
2422
|
+
const state2 = getState2();
|
|
2423
|
+
if (state2.configuration) return;
|
|
2424
|
+
state2.configuration = Object.freeze({ ...options });
|
|
2425
|
+
if (options.logLevel) import_api2.diag.setLogger(new import_api2.DiagConsoleLogger(), logLevel(options.logLevel));
|
|
2426
|
+
if (options.tracingEnabled === false) return;
|
|
2427
|
+
const baseUrl = options.baseUrl || process.env.TRACELOOP_BASE_URL || "https://api.traceloop.com";
|
|
2428
|
+
state2.defaultProcessor = createSpanProcessor({
|
|
2429
|
+
...options,
|
|
2430
|
+
baseUrl,
|
|
2431
|
+
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
2432
|
+
});
|
|
2433
|
+
const serviceResource = createResource({
|
|
2434
|
+
"service.name": options.appName || process.env.npm_package_name || "unknown_service"
|
|
2435
|
+
});
|
|
2436
|
+
const detectedResource = detectRuntimeResource();
|
|
2437
|
+
state2.provider = new import_sdk_trace_node.NodeTracerProvider({
|
|
2438
|
+
// Detected attributes win over the configured resource, matching
|
|
2439
|
+
// sdk-node's `this._resource.merge(detectResourcesSync(...))` so
|
|
2440
|
+
// OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES can still override appName.
|
|
2441
|
+
resource: detectedResource ? serviceResource.merge(detectedResource) : serviceResource,
|
|
2442
|
+
spanProcessors: [state2.defaultProcessor, ...options.processor ? [options.processor] : []]
|
|
2443
|
+
});
|
|
2444
|
+
state2.provider.register({
|
|
2445
|
+
contextManager: options.contextManager,
|
|
2446
|
+
propagator: options.propagator
|
|
2447
|
+
});
|
|
2448
|
+
const instrumentations = (_a = options.instrumentations) != null ? _a : [];
|
|
2449
|
+
if (contentCaptureDisabled(options)) {
|
|
2450
|
+
for (const instrumentation of instrumentations) {
|
|
2451
|
+
try {
|
|
2452
|
+
const config = {
|
|
2453
|
+
...instrumentation.getConfig(),
|
|
2454
|
+
traceContent: false
|
|
2455
|
+
};
|
|
2456
|
+
instrumentation.setConfig(config);
|
|
2457
|
+
} catch (e) {
|
|
2458
|
+
}
|
|
2218
2459
|
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2460
|
+
}
|
|
2461
|
+
(0, import_instrumentation.registerInstrumentations)({ instrumentations });
|
|
2462
|
+
}
|
|
2463
|
+
async function forceFlush() {
|
|
2464
|
+
var _a, _b;
|
|
2465
|
+
const state2 = getState2();
|
|
2466
|
+
try {
|
|
2467
|
+
await ((_a = state2.provider) == null ? void 0 : _a.forceFlush());
|
|
2468
|
+
await ((_b = state2.defaultProcessor) == null ? void 0 : _b.forceFlush());
|
|
2469
|
+
} catch (e) {
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
function withEntity(type, config, fn, args) {
|
|
2473
|
+
let entityContext = import_api2.context.active();
|
|
2474
|
+
if (type === import_ai_semantic_conventions.TraceloopSpanKindValues.WORKFLOW) {
|
|
2475
|
+
entityContext = entityContext.setValue(WORKFLOW_NAME_KEY, config.name);
|
|
2476
|
+
}
|
|
2477
|
+
const parentPath = entityContext.getValue(ENTITY_NAME_KEY);
|
|
2478
|
+
if (type === import_ai_semantic_conventions.TraceloopSpanKindValues.TASK || type === import_ai_semantic_conventions.TraceloopSpanKindValues.TOOL) {
|
|
2479
|
+
entityContext = entityContext.setValue(
|
|
2480
|
+
ENTITY_NAME_KEY,
|
|
2481
|
+
`${typeof parentPath === "string" ? `${parentPath}.` : ""}${config.name}`
|
|
2482
|
+
);
|
|
2483
|
+
}
|
|
2484
|
+
if (config.traceContent !== void 0) {
|
|
2485
|
+
entityContext = entityContext.setValue(import_ai_semantic_conventions.CONTEXT_KEY_ALLOW_TRACE_CONTENT, config.traceContent);
|
|
2486
|
+
}
|
|
2487
|
+
if (config.associationProperties) {
|
|
2488
|
+
entityContext = entityContext.setValue(
|
|
2489
|
+
ASSOCIATION_PROPERTIES_KEY,
|
|
2490
|
+
config.associationProperties
|
|
2491
|
+
);
|
|
2492
|
+
}
|
|
2493
|
+
if (config.suppressTracing) {
|
|
2494
|
+
entityContext = (0, import_core6.suppressTracing)(entityContext);
|
|
2495
|
+
}
|
|
2496
|
+
let callbackStarted = false;
|
|
2497
|
+
const run = (span) => {
|
|
2498
|
+
var _a;
|
|
2499
|
+
try {
|
|
2500
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_NAME, config.name);
|
|
2501
|
+
span.setAttribute(
|
|
2502
|
+
import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_PATH,
|
|
2503
|
+
typeof parentPath === "string" ? parentPath : ""
|
|
2504
|
+
);
|
|
2505
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_SPAN_KIND, type);
|
|
2506
|
+
if (type === import_ai_semantic_conventions.TraceloopSpanKindValues.WORKFLOW) {
|
|
2507
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_WORKFLOW_NAME, config.name);
|
|
2224
2508
|
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2509
|
+
if (config.version !== void 0)
|
|
2510
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_VERSION, config.version);
|
|
2511
|
+
const input = (_a = config.inputParameters) != null ? _a : args;
|
|
2512
|
+
if (shouldSendTraceContent()) {
|
|
2513
|
+
span.setAttribute(
|
|
2514
|
+
import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_INPUT,
|
|
2515
|
+
safeStringify(
|
|
2516
|
+
input.length === 1 && input[0] !== null && typeof input[0] === "object" && !(input[0] instanceof Map) ? { args: [], kwargs: input[0] } : { args: input, kwargs: {} }
|
|
2231
2517
|
)
|
|
2232
2518
|
);
|
|
2233
|
-
continue;
|
|
2234
2519
|
}
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
);
|
|
2243
|
-
this.inFlight.add(p);
|
|
2520
|
+
} catch (e) {
|
|
2521
|
+
}
|
|
2522
|
+
let result;
|
|
2523
|
+
try {
|
|
2524
|
+
callbackStarted = true;
|
|
2525
|
+
result = fn(...args);
|
|
2526
|
+
} catch (error) {
|
|
2244
2527
|
try {
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
if (this.debug) console.log(`[raindrop] direct: sent ${batch.length} spans`);
|
|
2248
|
-
} catch (err) {
|
|
2249
|
-
if (this.debug) {
|
|
2250
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2251
|
-
console.warn(`[raindrop] direct: failed to send spans (dropping): ${msg}`);
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2254
|
-
} finally {
|
|
2255
|
-
this.inFlight.delete(p);
|
|
2528
|
+
span.end();
|
|
2529
|
+
} catch (e) {
|
|
2256
2530
|
}
|
|
2531
|
+
throw error;
|
|
2257
2532
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
return { maxAttempts: 1, debug: this.debug, timeoutMs: POST_SHUTDOWN_TIMEOUT_MS };
|
|
2533
|
+
if (result instanceof Promise) {
|
|
2534
|
+
return result.then(
|
|
2535
|
+
(value) => {
|
|
2536
|
+
try {
|
|
2537
|
+
if (shouldSendTraceContent())
|
|
2538
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(value));
|
|
2539
|
+
span.end();
|
|
2540
|
+
} catch (e) {
|
|
2541
|
+
}
|
|
2542
|
+
return value;
|
|
2543
|
+
},
|
|
2544
|
+
(error) => {
|
|
2545
|
+
try {
|
|
2546
|
+
span.end();
|
|
2547
|
+
} catch (e) {
|
|
2548
|
+
}
|
|
2549
|
+
throw error;
|
|
2550
|
+
}
|
|
2551
|
+
);
|
|
2278
2552
|
}
|
|
2279
|
-
return { maxAttempts: 3, debug: this.debug };
|
|
2280
|
-
}
|
|
2281
|
-
async shutdown() {
|
|
2282
|
-
this.hasShutdown = true;
|
|
2283
|
-
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
2284
2553
|
try {
|
|
2285
|
-
if (
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
const drain = async () => {
|
|
2290
|
-
await this.flush();
|
|
2291
|
-
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
2292
|
-
})));
|
|
2293
|
-
};
|
|
2294
|
-
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
2295
|
-
if (!settled && this.debug) {
|
|
2296
|
-
console.warn("[raindrop] direct: shutdown deadline exceeded; abandoning in-flight spans");
|
|
2297
|
-
}
|
|
2298
|
-
} finally {
|
|
2299
|
-
this.shutdownDeadlineAt = void 0;
|
|
2554
|
+
if (shouldSendTraceContent())
|
|
2555
|
+
span.setAttribute(import_ai_semantic_conventions.SpanAttributes.TRACELOOP_ENTITY_OUTPUT, safeStringify(result));
|
|
2556
|
+
span.end();
|
|
2557
|
+
} catch (e) {
|
|
2300
2558
|
}
|
|
2559
|
+
return result;
|
|
2560
|
+
};
|
|
2561
|
+
try {
|
|
2562
|
+
const tracer = import_api2.trace.getTracer(TRACER_NAME);
|
|
2563
|
+
return import_api2.context.with(
|
|
2564
|
+
entityContext,
|
|
2565
|
+
() => tracer.startActiveSpan(`${config.name}.${type}`, {}, entityContext, run)
|
|
2566
|
+
);
|
|
2567
|
+
} catch (error) {
|
|
2568
|
+
if (callbackStarted) throw error;
|
|
2569
|
+
return fn(...args);
|
|
2301
2570
|
}
|
|
2302
|
-
}
|
|
2571
|
+
}
|
|
2572
|
+
function withTask(config, fn, ...args) {
|
|
2573
|
+
return withEntity(import_ai_semantic_conventions.TraceloopSpanKindValues.TASK, config, fn, args);
|
|
2574
|
+
}
|
|
2575
|
+
function withTool(config, fn, ...args) {
|
|
2576
|
+
return withEntity(import_ai_semantic_conventions.TraceloopSpanKindValues.TOOL, config, fn, args);
|
|
2577
|
+
}
|
|
2303
2578
|
|
|
2304
2579
|
// src/tracing/exit-flush.ts
|
|
2305
|
-
var
|
|
2580
|
+
var STATE_KEY4 = /* @__PURE__ */ Symbol.for("raindrop.tracing.exitFlushState");
|
|
2306
2581
|
function getState3() {
|
|
2307
2582
|
const holder = globalThis;
|
|
2308
|
-
let
|
|
2309
|
-
if (!
|
|
2310
|
-
|
|
2583
|
+
let state2 = holder[STATE_KEY4];
|
|
2584
|
+
if (!state2) {
|
|
2585
|
+
state2 = {
|
|
2311
2586
|
clientFlushers: /* @__PURE__ */ new Set(),
|
|
2312
2587
|
pipelineFlushNeeded: false,
|
|
2313
2588
|
handlerRegistered: false
|
|
2314
2589
|
};
|
|
2315
|
-
holder[
|
|
2590
|
+
holder[STATE_KEY4] = state2;
|
|
2316
2591
|
}
|
|
2317
|
-
return
|
|
2592
|
+
return state2;
|
|
2318
2593
|
}
|
|
2319
|
-
function ensureExitHandler(
|
|
2320
|
-
if (
|
|
2594
|
+
function ensureExitHandler(state2) {
|
|
2595
|
+
if (state2.handlerRegistered) return;
|
|
2321
2596
|
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
2322
|
-
|
|
2597
|
+
state2.handlerRegistered = true;
|
|
2323
2598
|
process.once("beforeExit", () => {
|
|
2324
2599
|
void flushAll();
|
|
2325
2600
|
});
|
|
2326
2601
|
}
|
|
2327
2602
|
function registerClientFlusher(flush) {
|
|
2328
|
-
const
|
|
2329
|
-
|
|
2330
|
-
ensureExitHandler(
|
|
2603
|
+
const state2 = getState3();
|
|
2604
|
+
state2.clientFlushers.add(flush);
|
|
2605
|
+
ensureExitHandler(state2);
|
|
2331
2606
|
return () => {
|
|
2332
|
-
|
|
2607
|
+
state2.clientFlushers.delete(flush);
|
|
2333
2608
|
};
|
|
2334
2609
|
}
|
|
2335
2610
|
function markPipelineForExitFlush() {
|
|
2336
|
-
const
|
|
2337
|
-
|
|
2338
|
-
ensureExitHandler(
|
|
2611
|
+
const state2 = getState3();
|
|
2612
|
+
state2.pipelineFlushNeeded = true;
|
|
2613
|
+
ensureExitHandler(state2);
|
|
2339
2614
|
}
|
|
2340
2615
|
async function flushAll() {
|
|
2341
|
-
const
|
|
2616
|
+
const state2 = getState3();
|
|
2342
2617
|
const tasks = [];
|
|
2343
|
-
for (const flush of
|
|
2618
|
+
for (const flush of state2.clientFlushers) {
|
|
2344
2619
|
tasks.push(Promise.resolve().then(flush).catch(() => {
|
|
2345
2620
|
}));
|
|
2346
2621
|
}
|
|
2347
|
-
if (
|
|
2622
|
+
if (state2.pipelineFlushNeeded) {
|
|
2348
2623
|
tasks.push(
|
|
2349
2624
|
Promise.resolve().then(() => forceFlush()).catch(() => {
|
|
2350
2625
|
})
|
|
@@ -3686,6 +3961,14 @@ if (localDebuggerEnabled()) {
|
|
|
3686
3961
|
process.env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = "http/json";
|
|
3687
3962
|
}
|
|
3688
3963
|
}
|
|
3964
|
+
var DropSpanExporter = class {
|
|
3965
|
+
export(_spans, resultCallback) {
|
|
3966
|
+
resultCallback({ code: 0 });
|
|
3967
|
+
}
|
|
3968
|
+
shutdown() {
|
|
3969
|
+
return Promise.resolve();
|
|
3970
|
+
}
|
|
3971
|
+
};
|
|
3689
3972
|
var CompositeSpanProcessor = class {
|
|
3690
3973
|
constructor(requiredProcessors, bestEffortProcessors) {
|
|
3691
3974
|
this.requiredProcessors = requiredProcessors;
|
|
@@ -3817,10 +4100,24 @@ function createLocalDebuggerSpanProcessor(options) {
|
|
|
3817
4100
|
url: `${localDebuggerUrl}traces`,
|
|
3818
4101
|
headers: {}
|
|
3819
4102
|
});
|
|
4103
|
+
if (!options.routeReplayTraces) {
|
|
4104
|
+
const exportLocal = localExporter.export.bind(localExporter);
|
|
4105
|
+
localExporter.export = (spans, callback) => {
|
|
4106
|
+
const localSpans = spans.filter(
|
|
4107
|
+
(span) => {
|
|
4108
|
+
var _a;
|
|
4109
|
+
return ((_a = replayTraceDestinationFor(span)) == null ? void 0 : _a.kind) !== "raindrop";
|
|
4110
|
+
}
|
|
4111
|
+
);
|
|
4112
|
+
if (localSpans.length === 0) callback({ code: 0 });
|
|
4113
|
+
else exportLocal(localSpans, callback);
|
|
4114
|
+
};
|
|
4115
|
+
}
|
|
3820
4116
|
try {
|
|
3821
4117
|
return createSpanProcessor({
|
|
3822
4118
|
apiKey: options.writeKey,
|
|
3823
4119
|
baseUrl: localDebuggerUrl,
|
|
4120
|
+
routeReplayTraces: options.routeReplayTraces,
|
|
3824
4121
|
disableBatch: options.disableBatching,
|
|
3825
4122
|
exporter: localExporter,
|
|
3826
4123
|
headers: {},
|
|
@@ -4234,7 +4531,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4234
4531
|
writeKey,
|
|
4235
4532
|
disableBatching,
|
|
4236
4533
|
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES,
|
|
4237
|
-
localDebuggerUrlOpt: localDebuggerUrl
|
|
4534
|
+
localDebuggerUrlOpt: localDebuggerUrl,
|
|
4535
|
+
routeReplayTraces: !cloudEnabledResolved
|
|
4238
4536
|
});
|
|
4239
4537
|
if (!cloudEnabledResolved) {
|
|
4240
4538
|
if (localDebuggerProcessor) {
|
|
@@ -4242,22 +4540,40 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4242
4540
|
baseUrl: apiUrl,
|
|
4243
4541
|
apiKey: writeKey,
|
|
4244
4542
|
...otherOptions,
|
|
4543
|
+
exporter: new DropSpanExporter(),
|
|
4245
4544
|
logLevel: logLevel2,
|
|
4246
4545
|
silenceInitializationMessage: true,
|
|
4247
4546
|
tracingEnabled: tracingEnabled !== false,
|
|
4248
4547
|
disableBatch: disableBatching,
|
|
4249
|
-
processor:
|
|
4548
|
+
processor: new CompositeSpanProcessor(
|
|
4549
|
+
[new RaindropContextSpanProcessor(), localDebuggerProcessor],
|
|
4550
|
+
[]
|
|
4551
|
+
),
|
|
4250
4552
|
instrumentations: createConfiguredInstrumentations(otherOptions)
|
|
4251
4553
|
});
|
|
4252
4554
|
traceloopInitialized = true;
|
|
4253
4555
|
markTraceloopConfiguredWithoutClaim();
|
|
4254
4556
|
} else {
|
|
4557
|
+
const replayOnlyProcessor = createSpanProcessor({
|
|
4558
|
+
exporter: new DropSpanExporter(),
|
|
4559
|
+
routeReplayTraces: true,
|
|
4560
|
+
disableBatch: disableBatching,
|
|
4561
|
+
allowedInstrumentationLibraries: ALL_INSTRUMENTATION_LIBRARIES
|
|
4562
|
+
});
|
|
4255
4563
|
initialize({
|
|
4256
4564
|
baseUrl: apiUrl,
|
|
4257
4565
|
apiKey: writeKey,
|
|
4566
|
+
...otherOptions,
|
|
4567
|
+
exporter: new DropSpanExporter(),
|
|
4258
4568
|
logLevel: logLevel2,
|
|
4259
4569
|
silenceInitializationMessage: true,
|
|
4260
|
-
tracingEnabled: false
|
|
4570
|
+
tracingEnabled: tracingEnabled !== false,
|
|
4571
|
+
disableBatch: disableBatching,
|
|
4572
|
+
processor: new CompositeSpanProcessor(
|
|
4573
|
+
[new RaindropContextSpanProcessor(), replayOnlyProcessor],
|
|
4574
|
+
[]
|
|
4575
|
+
),
|
|
4576
|
+
instrumentations: createConfiguredInstrumentations(otherOptions)
|
|
4261
4577
|
});
|
|
4262
4578
|
traceloopInitialized = true;
|
|
4263
4579
|
markTraceloopConfiguredWithoutClaim();
|
|
@@ -4285,7 +4601,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4285
4601
|
let guardedExporter;
|
|
4286
4602
|
try {
|
|
4287
4603
|
const callerExporter = otherOptions.exporter;
|
|
4288
|
-
|
|
4604
|
+
const guarded = callerExporter ? new GuardedSpanExporter(callerExporter, ownerHint) : buildGuardedExporter(apiUrl, exporterHeaders, ownerHint);
|
|
4605
|
+
guardedExporter = new ReplayRoutingSpanExporter(guarded);
|
|
4289
4606
|
} catch (guardError) {
|
|
4290
4607
|
releasePipelineClaim();
|
|
4291
4608
|
claimedPipeline = false;
|
|
@@ -4536,7 +4853,8 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4536
4853
|
writeKey,
|
|
4537
4854
|
disableBatching,
|
|
4538
4855
|
allowedInstrumentationLibraries: processorOptions == null ? void 0 : processorOptions.allowedInstrumentationLibraries,
|
|
4539
|
-
localDebuggerUrlOpt: localDebuggerUrl
|
|
4856
|
+
localDebuggerUrlOpt: localDebuggerUrl,
|
|
4857
|
+
routeReplayTraces: true
|
|
4540
4858
|
});
|
|
4541
4859
|
return withV2SpanCompat(
|
|
4542
4860
|
localOnlyProcessor != null ? localOnlyProcessor : {
|
|
@@ -4557,6 +4875,7 @@ var tracing = (analytics, apiUrl, writeKey, options, isDebug = false) => {
|
|
|
4557
4875
|
apiKey: writeKey,
|
|
4558
4876
|
disableBatch: disableBatching,
|
|
4559
4877
|
...processorOptions != null ? processorOptions : {},
|
|
4878
|
+
routeReplayTraces: true,
|
|
4560
4879
|
...headers ? { headers } : {}
|
|
4561
4880
|
});
|
|
4562
4881
|
const localDebuggerProcessor = createLocalDebuggerSpanProcessor({
|