@raindrop-ai/deep-agents 0.0.6 → 0.1.1
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 +1 -11
- package/dist/index.d.mts +31 -6
- package/dist/index.d.ts +31 -6
- package/dist/index.js +534 -121
- package/dist/index.mjs +534 -121
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -28,7 +28,69 @@ module.exports = __toCommonJS(index_exports);
|
|
|
28
28
|
// src/callback-handler.ts
|
|
29
29
|
var import_base = require("@langchain/core/callbacks/base");
|
|
30
30
|
|
|
31
|
-
// ../core/dist/chunk-
|
|
31
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
32
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
33
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
34
|
+
var EvalScopeStorage = class {
|
|
35
|
+
constructor() {
|
|
36
|
+
this._als = null;
|
|
37
|
+
this._probed = false;
|
|
38
|
+
}
|
|
39
|
+
maybeAdoptAsyncLocalStorage() {
|
|
40
|
+
if (this._probed) return;
|
|
41
|
+
this._probed = true;
|
|
42
|
+
try {
|
|
43
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
44
|
+
if (!Ctor) return;
|
|
45
|
+
const als = new Ctor();
|
|
46
|
+
als.run(PROBE_SCOPE, () => {
|
|
47
|
+
});
|
|
48
|
+
this._als = als;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
this._als = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
run(scope, callback) {
|
|
54
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
55
|
+
if (this._als) return this._als.run(scope, callback);
|
|
56
|
+
const previous = this._syncScope;
|
|
57
|
+
this._syncScope = scope;
|
|
58
|
+
try {
|
|
59
|
+
return callback();
|
|
60
|
+
} finally {
|
|
61
|
+
this._syncScope = previous;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
current() {
|
|
65
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
66
|
+
if (this._als) return this._als.getStore();
|
|
67
|
+
return this._syncScope;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
71
|
+
function evalScopeStorage() {
|
|
72
|
+
const holder = globalThis;
|
|
73
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
74
|
+
if (!storage) {
|
|
75
|
+
storage = new EvalScopeStorage();
|
|
76
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
77
|
+
}
|
|
78
|
+
return storage;
|
|
79
|
+
}
|
|
80
|
+
function currentEvalScope() {
|
|
81
|
+
try {
|
|
82
|
+
return evalScopeStorage().current();
|
|
83
|
+
} catch (e) {
|
|
84
|
+
return void 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function evalScopeAttributes() {
|
|
88
|
+
const scope = currentEvalScope();
|
|
89
|
+
if (!scope) return {};
|
|
90
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ../core/dist/chunk-T53LQAH7.js
|
|
32
94
|
function getCrypto() {
|
|
33
95
|
const c = globalThis.crypto;
|
|
34
96
|
return c;
|
|
@@ -83,6 +145,39 @@ function base64Encode(bytes) {
|
|
|
83
145
|
}
|
|
84
146
|
return out;
|
|
85
147
|
}
|
|
148
|
+
function base64ToHex(value) {
|
|
149
|
+
if (!value) return "";
|
|
150
|
+
const maybeBuffer = globalThis.Buffer;
|
|
151
|
+
if (maybeBuffer) {
|
|
152
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
153
|
+
}
|
|
154
|
+
const atobFn = globalThis.atob;
|
|
155
|
+
if (typeof atobFn !== "function") return "";
|
|
156
|
+
try {
|
|
157
|
+
const binary = atobFn(value);
|
|
158
|
+
let hex = "";
|
|
159
|
+
for (let i = 0; i < binary.length; i++) {
|
|
160
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
161
|
+
}
|
|
162
|
+
return hex;
|
|
163
|
+
} catch (e) {
|
|
164
|
+
return "";
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
168
|
+
mode: "raindrop.handoff.mode",
|
|
169
|
+
childEventId: "raindrop.handoff.childEventId",
|
|
170
|
+
parentEventId: "raindrop.handoff.parentEventId",
|
|
171
|
+
parentSpanId: "raindrop.handoff.parentSpanId",
|
|
172
|
+
name: "raindrop.handoff.name",
|
|
173
|
+
terminal: "raindrop.handoff.terminal",
|
|
174
|
+
agentRole: "raindrop.agent.role"
|
|
175
|
+
};
|
|
176
|
+
var HANDOFF_TERMINAL_PROPERTY_KEY = HANDOFF_ATTRIBUTE_SUFFIXES.terminal;
|
|
177
|
+
var TRACEPARENT_HEADER = "traceparent";
|
|
178
|
+
var BAGGAGE_HEADER = "baggage";
|
|
179
|
+
var HANDOFF_HEADER = "x-raindrop-handoff";
|
|
180
|
+
var UNRESOLVED_CARRIER_WARNING = `[raindrop] resume: headers were supplied but no hand-off carrier was found on them (searched ${HANDOFF_HEADER}, ${TRACEPARENT_HEADER}, ${BAGGAGE_HEADER}). This run reports as an UNLINKED event, and the launcher that dispatched it will stay on "queued" forever because nothing ever references its child. Passing headers means a parent handed off, so no carrier on them is almost certainly a defect: a gateway or proxy stripping ${HANDOFF_HEADER}, a middleware overwriting ${BAGGAGE_HEADER}, a request forwarded without its headers, or a hand-built carrier whose field names do not match. Send every header the launcher's dispatch returned. Logged once per process; pass no headers for a directly-invoked sub-agent to silence it.`;
|
|
86
181
|
function runWithTracingSuppressed(fn) {
|
|
87
182
|
const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
|
|
88
183
|
if (typeof hook !== "function") return fn();
|
|
@@ -210,6 +305,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
210
305
|
const resp = await runWithTracingSuppressed(
|
|
211
306
|
() => fetch(url, {
|
|
212
307
|
method: "POST",
|
|
308
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
213
309
|
headers: {
|
|
214
310
|
"Content-Type": "application/json",
|
|
215
311
|
...headers
|
|
@@ -311,6 +407,55 @@ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", se
|
|
|
311
407
|
]
|
|
312
408
|
};
|
|
313
409
|
}
|
|
410
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
411
|
+
function state() {
|
|
412
|
+
const holder = globalThis;
|
|
413
|
+
let current = holder[STATE_KEY];
|
|
414
|
+
if (!current) {
|
|
415
|
+
let storage = null;
|
|
416
|
+
try {
|
|
417
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
418
|
+
if (Ctor) storage = new Ctor();
|
|
419
|
+
} catch (e) {
|
|
420
|
+
storage = null;
|
|
421
|
+
}
|
|
422
|
+
current = {
|
|
423
|
+
storage,
|
|
424
|
+
syncDestination: void 0,
|
|
425
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
426
|
+
};
|
|
427
|
+
holder[STATE_KEY] = current;
|
|
428
|
+
}
|
|
429
|
+
return current;
|
|
430
|
+
}
|
|
431
|
+
function currentReplayTraceDestination() {
|
|
432
|
+
var _a, _b;
|
|
433
|
+
const routing = state();
|
|
434
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
435
|
+
}
|
|
436
|
+
function rememberReplayTraceDestination(span) {
|
|
437
|
+
const destination = currentReplayTraceDestination();
|
|
438
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
439
|
+
}
|
|
440
|
+
function copyReplayTraceDestination(source, target) {
|
|
441
|
+
const destination = state().spanDestinations.get(source);
|
|
442
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
443
|
+
}
|
|
444
|
+
function replayTraceDestinationFor(value) {
|
|
445
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
446
|
+
return void 0;
|
|
447
|
+
}
|
|
448
|
+
return state().spanDestinations.get(value);
|
|
449
|
+
}
|
|
450
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
451
|
+
var _a, _b;
|
|
452
|
+
if (!destination || !spanId || !traceId) return;
|
|
453
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
454
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
455
|
+
}
|
|
456
|
+
function replayTraceUrl(baseUrl) {
|
|
457
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
458
|
+
}
|
|
314
459
|
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
315
460
|
var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
|
|
316
461
|
var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
|
|
@@ -373,26 +518,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
373
518
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
374
519
|
return null;
|
|
375
520
|
}
|
|
521
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
376
522
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
377
523
|
var _a;
|
|
378
524
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
379
|
-
if (!baseUrl) return;
|
|
380
|
-
|
|
525
|
+
if (!baseUrl) return Promise.resolve();
|
|
526
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
381
527
|
maxAttempts: 1,
|
|
382
528
|
debug: (_a = options.debug) != null ? _a : false,
|
|
383
|
-
sdkName: options.sdkName
|
|
529
|
+
sdkName: options.sdkName,
|
|
530
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
384
531
|
}).catch(() => {
|
|
385
532
|
});
|
|
386
533
|
}
|
|
387
534
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
388
535
|
var _a;
|
|
389
536
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
390
|
-
if (!baseUrl) return;
|
|
537
|
+
if (!baseUrl) return Promise.resolve();
|
|
391
538
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
392
|
-
|
|
539
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
393
540
|
maxAttempts: 1,
|
|
394
541
|
debug: (_a = options.debug) != null ? _a : false,
|
|
395
|
-
sdkName: options.sdkName
|
|
542
|
+
sdkName: options.sdkName,
|
|
543
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
396
544
|
}).catch(() => {
|
|
397
545
|
});
|
|
398
546
|
}
|
|
@@ -418,16 +566,52 @@ function projectIdHeaders(projectId) {
|
|
|
418
566
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
419
567
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
420
568
|
function mergePatches(target, source) {
|
|
421
|
-
var _a, _b, _c, _d;
|
|
569
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
422
570
|
const out = { ...target, ...source };
|
|
423
571
|
if (target.properties || source.properties) {
|
|
424
572
|
out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
|
|
425
573
|
}
|
|
574
|
+
if (target.usage || source.usage) {
|
|
575
|
+
out.usage = { ...(_c = target.usage) != null ? _c : {} };
|
|
576
|
+
if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
|
|
577
|
+
out.usage.promptTokens = source.usage.promptTokens;
|
|
578
|
+
}
|
|
579
|
+
if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
|
|
580
|
+
out.usage.completionTokens = source.usage.completionTokens;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (source.error === void 0) {
|
|
584
|
+
out.error = target.error;
|
|
585
|
+
}
|
|
586
|
+
if (target.featureFlags || source.featureFlags) {
|
|
587
|
+
out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
|
|
588
|
+
}
|
|
426
589
|
if (target.attachments || source.attachments) {
|
|
427
|
-
out.attachments = [...(
|
|
590
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
428
591
|
}
|
|
429
592
|
return out;
|
|
430
593
|
}
|
|
594
|
+
function isErrorLike(value) {
|
|
595
|
+
return value !== null && typeof value === "object";
|
|
596
|
+
}
|
|
597
|
+
function eventTelemetryProperties(patch) {
|
|
598
|
+
var _a, _b;
|
|
599
|
+
const properties = {};
|
|
600
|
+
if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
|
|
601
|
+
properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
|
|
602
|
+
}
|
|
603
|
+
if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
|
|
604
|
+
properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
|
|
605
|
+
}
|
|
606
|
+
if (patch.error !== void 0 && patch.error !== null) {
|
|
607
|
+
const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
|
|
608
|
+
const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
|
|
609
|
+
const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
|
|
610
|
+
properties["error.type"] = errorType;
|
|
611
|
+
properties["error.message"] = errorMessage;
|
|
612
|
+
}
|
|
613
|
+
return properties;
|
|
614
|
+
}
|
|
431
615
|
var EventShipper = class {
|
|
432
616
|
constructor(opts) {
|
|
433
617
|
this.buffers = /* @__PURE__ */ new Map();
|
|
@@ -513,6 +697,15 @@ var EventShipper = class {
|
|
|
513
697
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
514
698
|
if (!this.enabled) return;
|
|
515
699
|
if (!eventId || !eventId.trim()) return;
|
|
700
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
701
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
702
|
+
const destination = currentReplayTraceDestination();
|
|
703
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
704
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
705
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
706
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
516
709
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
517
710
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
518
711
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -571,6 +764,9 @@ var EventShipper = class {
|
|
|
571
764
|
try {
|
|
572
765
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
573
766
|
this.timers.clear();
|
|
767
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
768
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
769
|
+
}
|
|
574
770
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
575
771
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
576
772
|
} finally {
|
|
@@ -580,6 +776,8 @@ var EventShipper = class {
|
|
|
580
776
|
async trackSignal(signal) {
|
|
581
777
|
var _a, _b;
|
|
582
778
|
if (!this.enabled) return;
|
|
779
|
+
const destination = currentReplayTraceDestination();
|
|
780
|
+
if (destination && destination.kind !== "workshop") return;
|
|
583
781
|
const body = [
|
|
584
782
|
{
|
|
585
783
|
event_id: signal.eventId,
|
|
@@ -614,6 +812,8 @@ var EventShipper = class {
|
|
|
614
812
|
}
|
|
615
813
|
async identify(users) {
|
|
616
814
|
if (!this.enabled) return;
|
|
815
|
+
const destination = currentReplayTraceDestination();
|
|
816
|
+
if (destination && destination.kind !== "workshop") return;
|
|
617
817
|
const list = Array.isArray(users) ? users : [users];
|
|
618
818
|
const body = list.filter((user) => {
|
|
619
819
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -666,8 +866,9 @@ var EventShipper = class {
|
|
|
666
866
|
this.buffers.delete(eventId);
|
|
667
867
|
if (!accumulated) return;
|
|
668
868
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
669
|
-
const
|
|
670
|
-
const
|
|
869
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
870
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
871
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
671
872
|
if (!userId) {
|
|
672
873
|
if (this.debug) {
|
|
673
874
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -675,9 +876,13 @@ var EventShipper = class {
|
|
|
675
876
|
this.sticky.delete(eventId);
|
|
676
877
|
return;
|
|
677
878
|
}
|
|
678
|
-
const { wizardSession, ...restProperties } = (
|
|
679
|
-
|
|
680
|
-
|
|
879
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
880
|
+
let telemetryProperties = {};
|
|
881
|
+
try {
|
|
882
|
+
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
883
|
+
} catch (e) {
|
|
884
|
+
}
|
|
885
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
681
886
|
const payload = {
|
|
682
887
|
event_id: eventId,
|
|
683
888
|
user_id: userId,
|
|
@@ -685,15 +890,17 @@ var EventShipper = class {
|
|
|
685
890
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
686
891
|
ai_data: {
|
|
687
892
|
input: accumulated.input,
|
|
688
|
-
output: accumulated.output,
|
|
893
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
689
894
|
model: accumulated.model,
|
|
690
895
|
convo_id: convoId
|
|
691
896
|
},
|
|
692
897
|
properties: {
|
|
693
898
|
...restProperties,
|
|
899
|
+
...telemetryProperties,
|
|
694
900
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
695
901
|
$context: this.context
|
|
696
902
|
},
|
|
903
|
+
...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
|
|
697
904
|
attachments: accumulated.attachments,
|
|
698
905
|
is_pending: isPending
|
|
699
906
|
};
|
|
@@ -717,29 +924,30 @@ var EventShipper = class {
|
|
|
717
924
|
endpoint: url
|
|
718
925
|
});
|
|
719
926
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
});
|
|
727
|
-
}
|
|
927
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
928
|
+
baseUrl: this.localDebuggerUrl,
|
|
929
|
+
writeKey: this.writeKey,
|
|
930
|
+
debug: this.debug,
|
|
931
|
+
sdkName: this.sdkName
|
|
932
|
+
}) : void 0;
|
|
728
933
|
if (!this.writeKey) {
|
|
729
934
|
if (!isPending) this.sticky.delete(eventId);
|
|
935
|
+
if (mirror) await mirror;
|
|
730
936
|
return;
|
|
731
937
|
}
|
|
732
938
|
const opts = this.requestOpts();
|
|
733
939
|
if (!opts) {
|
|
734
940
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
735
941
|
if (!isPending) this.sticky.delete(eventId);
|
|
942
|
+
if (mirror) await mirror;
|
|
736
943
|
return;
|
|
737
944
|
}
|
|
738
945
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
739
|
-
|
|
946
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
947
|
+
this.inFlight.add(combined);
|
|
740
948
|
try {
|
|
741
949
|
try {
|
|
742
|
-
await
|
|
950
|
+
await combined;
|
|
743
951
|
if (this.debug) {
|
|
744
952
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
745
953
|
}
|
|
@@ -751,13 +959,156 @@ var EventShipper = class {
|
|
|
751
959
|
);
|
|
752
960
|
}
|
|
753
961
|
} finally {
|
|
754
|
-
this.inFlight.delete(
|
|
962
|
+
this.inFlight.delete(combined);
|
|
755
963
|
}
|
|
756
964
|
if (!isPending) {
|
|
757
965
|
this.sticky.delete(eventId);
|
|
758
966
|
}
|
|
759
967
|
}
|
|
760
968
|
};
|
|
969
|
+
var MODEL_USAGE_ATTRIBUTES = {
|
|
970
|
+
usageSource: "raindrop.usage.source",
|
|
971
|
+
providerName: "gen_ai.provider.name",
|
|
972
|
+
requestModel: "gen_ai.request.model",
|
|
973
|
+
responseModel: "gen_ai.response.model",
|
|
974
|
+
inputTokens: "gen_ai.usage.input_tokens",
|
|
975
|
+
outputTokens: "gen_ai.usage.output_tokens",
|
|
976
|
+
reasoningTokens: "gen_ai.usage.reasoning_tokens",
|
|
977
|
+
cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
|
|
978
|
+
cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
|
|
979
|
+
providerReportedCost: "gen_ai.usage.provider_reported_cost",
|
|
980
|
+
nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
|
|
981
|
+
nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
|
|
982
|
+
totalOutputTokens: "raindrop.usage.output_tokens.total",
|
|
983
|
+
reasoningOutputTokens: "raindrop.usage.output_tokens.reasoning",
|
|
984
|
+
cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
|
|
985
|
+
cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
|
|
986
|
+
};
|
|
987
|
+
var MODEL_PROVIDER_NAMES = [
|
|
988
|
+
["google.vertex.anthropic", "google-vertex"],
|
|
989
|
+
["google.vertex_ai", "google-vertex"],
|
|
990
|
+
["google.vertex", "google-vertex"],
|
|
991
|
+
["gcp.vertex_ai", "google-vertex"],
|
|
992
|
+
["gcp.gemini", "google"],
|
|
993
|
+
["google_vertexai", "google-vertex"],
|
|
994
|
+
["vertex.anthropic", "google-vertex"],
|
|
995
|
+
["amazon-bedrock", "amazon-bedrock"],
|
|
996
|
+
["aws.bedrock", "amazon-bedrock"],
|
|
997
|
+
["bedrock", "amazon-bedrock"],
|
|
998
|
+
["anthropic", "anthropic"],
|
|
999
|
+
["openai", "openai"],
|
|
1000
|
+
["google", "google"],
|
|
1001
|
+
["az.ai.openai", "azure"],
|
|
1002
|
+
["azure", "azure"],
|
|
1003
|
+
["openrouter", "openrouter"]
|
|
1004
|
+
];
|
|
1005
|
+
function canonicalModelProvider(provider) {
|
|
1006
|
+
var _a;
|
|
1007
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
1008
|
+
if (normalizedProvider === "gateway") return "vercel";
|
|
1009
|
+
const match = MODEL_PROVIDER_NAMES.find(
|
|
1010
|
+
([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
|
|
1011
|
+
);
|
|
1012
|
+
return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
|
|
1013
|
+
}
|
|
1014
|
+
var STRING_ALIASES = {
|
|
1015
|
+
[MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
|
|
1016
|
+
};
|
|
1017
|
+
var NUMBER_ALIASES = {
|
|
1018
|
+
[MODEL_USAGE_ATTRIBUTES.inputTokens]: [
|
|
1019
|
+
"gen_ai.usage.prompt_tokens",
|
|
1020
|
+
"ai.usage.prompt_tokens",
|
|
1021
|
+
"ai.usage.promptTokens",
|
|
1022
|
+
"ai.usage.input_tokens",
|
|
1023
|
+
"ai.usage.inputTokens"
|
|
1024
|
+
],
|
|
1025
|
+
[MODEL_USAGE_ATTRIBUTES.outputTokens]: [
|
|
1026
|
+
"gen_ai.usage.completion_tokens",
|
|
1027
|
+
"ai.usage.completion_tokens",
|
|
1028
|
+
"ai.usage.completionTokens",
|
|
1029
|
+
"ai.usage.output_tokens",
|
|
1030
|
+
"ai.usage.outputTokens"
|
|
1031
|
+
],
|
|
1032
|
+
[MODEL_USAGE_ATTRIBUTES.reasoningTokens]: [
|
|
1033
|
+
"gen_ai.usage.reasoning.output_tokens",
|
|
1034
|
+
"ai.usage.reasoningTokens",
|
|
1035
|
+
"ai.usage.thoughts_tokens"
|
|
1036
|
+
],
|
|
1037
|
+
[MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens]: [
|
|
1038
|
+
"gen_ai.usage.cache_read_tokens",
|
|
1039
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
1040
|
+
"ai.usage.cachedInputTokens",
|
|
1041
|
+
"ai.usage.cached_tokens",
|
|
1042
|
+
"ai.usage.cache_read_tokens",
|
|
1043
|
+
"ai.usage.cache_read_input_tokens",
|
|
1044
|
+
"ai.usage.cacheReadInputTokens"
|
|
1045
|
+
],
|
|
1046
|
+
[MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens]: [
|
|
1047
|
+
"gen_ai.usage.cache_creation_input_tokens",
|
|
1048
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
1049
|
+
"ai.usage.cacheWriteInputTokens",
|
|
1050
|
+
"ai.usage.cache_creation_input_tokens",
|
|
1051
|
+
"ai.usage.cacheCreationInputTokens"
|
|
1052
|
+
]
|
|
1053
|
+
};
|
|
1054
|
+
function hasAttribute(attributes, key) {
|
|
1055
|
+
return attributes.some((attribute) => attribute.key === key);
|
|
1056
|
+
}
|
|
1057
|
+
function findStringAttribute(attributes, keys) {
|
|
1058
|
+
return attributes.find(
|
|
1059
|
+
(attribute) => keys.includes(attribute.key) && typeof attribute.value.stringValue === "string" && attribute.value.stringValue.length > 0
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1062
|
+
function findNumberAttribute(attributes, keys) {
|
|
1063
|
+
return attributes.find((attribute) => {
|
|
1064
|
+
if (!keys.includes(attribute.key)) return false;
|
|
1065
|
+
if (typeof attribute.value.doubleValue === "number" && Number.isSafeInteger(attribute.value.doubleValue) && attribute.value.doubleValue >= 0) {
|
|
1066
|
+
return true;
|
|
1067
|
+
}
|
|
1068
|
+
const intValue = attribute.value.intValue;
|
|
1069
|
+
return integerValue(intValue) !== void 0;
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
function integerValue(value) {
|
|
1073
|
+
if (typeof value === "number") {
|
|
1074
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
1075
|
+
}
|
|
1076
|
+
if (typeof value !== "string") return void 0;
|
|
1077
|
+
const parsed = Number(value);
|
|
1078
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
1079
|
+
}
|
|
1080
|
+
function appendAlias(attributes, target, source) {
|
|
1081
|
+
if (!source || hasAttribute(attributes, target)) return attributes;
|
|
1082
|
+
return [...attributes, { key: target, value: { ...source.value } }];
|
|
1083
|
+
}
|
|
1084
|
+
function appendProviderAlias(attributes) {
|
|
1085
|
+
if (hasAttribute(attributes, MODEL_USAGE_ATTRIBUTES.providerName)) return attributes;
|
|
1086
|
+
const source = findStringAttribute(attributes, ["gen_ai.system", "ai.model.provider"]);
|
|
1087
|
+
if (!(source == null ? void 0 : source.value.stringValue)) return attributes;
|
|
1088
|
+
const attribute = attrString(
|
|
1089
|
+
MODEL_USAGE_ATTRIBUTES.providerName,
|
|
1090
|
+
canonicalModelProvider(source.value.stringValue)
|
|
1091
|
+
);
|
|
1092
|
+
return attribute ? [...attributes, attribute] : attributes;
|
|
1093
|
+
}
|
|
1094
|
+
function normalizeModelUsageSpan(span) {
|
|
1095
|
+
const original = span.attributes;
|
|
1096
|
+
if (!original || original.length === 0) return span;
|
|
1097
|
+
const responseModel = findStringAttribute(original, [
|
|
1098
|
+
MODEL_USAGE_ATTRIBUTES.responseModel,
|
|
1099
|
+
"ai.response.model"
|
|
1100
|
+
]);
|
|
1101
|
+
if (!responseModel) return span;
|
|
1102
|
+
let attributes = appendAlias(original, MODEL_USAGE_ATTRIBUTES.responseModel, responseModel);
|
|
1103
|
+
attributes = appendProviderAlias(attributes);
|
|
1104
|
+
for (const [target, aliases] of Object.entries(STRING_ALIASES)) {
|
|
1105
|
+
attributes = appendAlias(attributes, target, findStringAttribute(attributes, aliases));
|
|
1106
|
+
}
|
|
1107
|
+
for (const [target, aliases] of Object.entries(NUMBER_ALIASES)) {
|
|
1108
|
+
attributes = appendAlias(attributes, target, findNumberAttribute(attributes, aliases));
|
|
1109
|
+
}
|
|
1110
|
+
return attributes === original ? span : { ...span, attributes };
|
|
1111
|
+
}
|
|
761
1112
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
762
1113
|
"apikey",
|
|
763
1114
|
"apisecret",
|
|
@@ -847,6 +1198,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
847
1198
|
if (scrubbedJson === json) return void 0;
|
|
848
1199
|
return { stringValue: scrubbedJson };
|
|
849
1200
|
}
|
|
1201
|
+
function identityAttrs(args) {
|
|
1202
|
+
return [
|
|
1203
|
+
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
1204
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
|
|
1205
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
|
|
1206
|
+
];
|
|
1207
|
+
}
|
|
850
1208
|
function applyOtelSpanAttributeLimit(limit) {
|
|
851
1209
|
var _a, _b;
|
|
852
1210
|
try {
|
|
@@ -942,7 +1300,10 @@ var TraceShipper = class {
|
|
|
942
1300
|
try {
|
|
943
1301
|
const result = this.transformSpanHook(current);
|
|
944
1302
|
if (result === null) return null;
|
|
945
|
-
if (result !== void 0)
|
|
1303
|
+
if (result !== void 0) {
|
|
1304
|
+
copyReplayTraceDestination(current, result);
|
|
1305
|
+
current = result;
|
|
1306
|
+
}
|
|
946
1307
|
} catch (err) {
|
|
947
1308
|
if (this.debug) {
|
|
948
1309
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -951,10 +1312,20 @@ var TraceShipper = class {
|
|
|
951
1312
|
return null;
|
|
952
1313
|
}
|
|
953
1314
|
}
|
|
1315
|
+
try {
|
|
1316
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1317
|
+
copyReplayTraceDestination(current, normalized);
|
|
1318
|
+
current = normalized;
|
|
1319
|
+
} catch (e) {
|
|
1320
|
+
}
|
|
954
1321
|
if (!this.disableDefaultRedaction) {
|
|
955
|
-
|
|
1322
|
+
const redacted = defaultTransformSpan(current);
|
|
1323
|
+
copyReplayTraceDestination(current, redacted);
|
|
1324
|
+
current = redacted;
|
|
956
1325
|
}
|
|
957
|
-
|
|
1326
|
+
const capped = this.capSpanAttributes(current);
|
|
1327
|
+
copyReplayTraceDestination(current, capped);
|
|
1328
|
+
return capped;
|
|
958
1329
|
}
|
|
959
1330
|
isDebugEnabled() {
|
|
960
1331
|
return this.debug;
|
|
@@ -971,33 +1342,55 @@ var TraceShipper = class {
|
|
|
971
1342
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
972
1343
|
const attrs = [
|
|
973
1344
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
974
|
-
|
|
1345
|
+
...identityAttrs(args),
|
|
1346
|
+
attrString("ai.operationId", args.operationId),
|
|
1347
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
975
1348
|
];
|
|
976
1349
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
977
|
-
const span = {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1350
|
+
const span = {
|
|
1351
|
+
ids,
|
|
1352
|
+
name: args.name,
|
|
1353
|
+
startTimeUnixNano: started,
|
|
1354
|
+
attributes: attrs
|
|
1355
|
+
};
|
|
1356
|
+
rememberReplayTraceDestination(span);
|
|
1357
|
+
const openSpan = buildOtlpSpan({
|
|
1358
|
+
ids: span.ids,
|
|
1359
|
+
name: span.name,
|
|
1360
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1361
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1362
|
+
// placeholder — will be updated on endSpan
|
|
1363
|
+
attributes: span.attributes,
|
|
1364
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1365
|
+
});
|
|
1366
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1367
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
989
1368
|
return span;
|
|
990
1369
|
}
|
|
991
|
-
mirrorToLocalDebugger(span) {
|
|
992
|
-
|
|
1370
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1371
|
+
const destination = replayTraceDestinationFor(span);
|
|
1372
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1373
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1374
|
+
if (!localDebuggerUrl) return;
|
|
993
1375
|
const redacted = this.redactSpan(span);
|
|
994
1376
|
if (redacted === null) return;
|
|
1377
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1378
|
+
recordReplayExportedSpan(
|
|
1379
|
+
destination,
|
|
1380
|
+
base64ToHex(redacted.spanId),
|
|
1381
|
+
base64ToHex(redacted.traceId)
|
|
1382
|
+
);
|
|
1383
|
+
}
|
|
995
1384
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
996
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
997
|
-
baseUrl:
|
|
1385
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1386
|
+
baseUrl: localDebuggerUrl,
|
|
998
1387
|
debug: false,
|
|
999
1388
|
sdkName: this.sdkName
|
|
1000
1389
|
});
|
|
1390
|
+
this.inFlight.add(p);
|
|
1391
|
+
void p.finally(() => {
|
|
1392
|
+
this.inFlight.delete(p);
|
|
1393
|
+
});
|
|
1001
1394
|
}
|
|
1002
1395
|
endSpan(span, extra) {
|
|
1003
1396
|
var _a, _b;
|
|
@@ -1019,14 +1412,17 @@ var TraceShipper = class {
|
|
|
1019
1412
|
attributes: span.attributes,
|
|
1020
1413
|
status
|
|
1021
1414
|
});
|
|
1415
|
+
copyReplayTraceDestination(span, otlp);
|
|
1022
1416
|
this.enqueue(otlp);
|
|
1023
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1417
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1024
1418
|
}
|
|
1025
1419
|
createSpan(args) {
|
|
1026
1420
|
var _a;
|
|
1027
1421
|
const ids = createSpanIds(args.parent);
|
|
1028
1422
|
const attrs = [
|
|
1029
|
-
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
|
|
1423
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1424
|
+
...identityAttrs(args),
|
|
1425
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1030
1426
|
];
|
|
1031
1427
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1032
1428
|
const otlp = buildOtlpSpan({
|
|
@@ -1037,8 +1433,9 @@ var TraceShipper = class {
|
|
|
1037
1433
|
attributes: attrs,
|
|
1038
1434
|
status: args.status
|
|
1039
1435
|
});
|
|
1436
|
+
rememberReplayTraceDestination(otlp);
|
|
1040
1437
|
this.enqueue(otlp);
|
|
1041
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1438
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1042
1439
|
}
|
|
1043
1440
|
enqueue(span) {
|
|
1044
1441
|
if (!this.enabled) return;
|
|
@@ -1052,6 +1449,13 @@ var TraceShipper = class {
|
|
|
1052
1449
|
}
|
|
1053
1450
|
const redacted = this.redactSpan(span);
|
|
1054
1451
|
if (redacted === null) return;
|
|
1452
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1453
|
+
recordReplayExportedSpan(
|
|
1454
|
+
destination,
|
|
1455
|
+
base64ToHex(redacted.spanId),
|
|
1456
|
+
base64ToHex(redacted.traceId)
|
|
1457
|
+
);
|
|
1458
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1055
1459
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1056
1460
|
this.queue.shift();
|
|
1057
1461
|
}
|
|
@@ -1070,47 +1474,67 @@ var TraceShipper = class {
|
|
|
1070
1474
|
}
|
|
1071
1475
|
}
|
|
1072
1476
|
async flush() {
|
|
1073
|
-
|
|
1477
|
+
var _a;
|
|
1478
|
+
if (!this.enabled) {
|
|
1479
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1480
|
+
})));
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1074
1483
|
if (this.timer) {
|
|
1075
1484
|
clearTimeout(this.timer);
|
|
1076
1485
|
this.timer = void 0;
|
|
1077
1486
|
}
|
|
1078
1487
|
while (this.queue.length > 0) {
|
|
1079
1488
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1080
|
-
|
|
1081
|
-
const
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1087
|
-
)
|
|
1088
|
-
);
|
|
1089
|
-
continue;
|
|
1090
|
-
}
|
|
1091
|
-
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
1092
|
-
const url = `${this.baseUrl}traces`;
|
|
1093
|
-
if (this.debug) {
|
|
1094
|
-
console.log(`${this.prefix} sending traces batch`, {
|
|
1095
|
-
spans: batch.length,
|
|
1096
|
-
endpoint: url
|
|
1097
|
-
});
|
|
1489
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1490
|
+
for (const span of batch) {
|
|
1491
|
+
const destination = replayTraceDestinationFor(span);
|
|
1492
|
+
const spans = groups.get(destination);
|
|
1493
|
+
if (spans) spans.push(span);
|
|
1494
|
+
else groups.set(destination, [span]);
|
|
1098
1495
|
}
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1105
|
-
} catch (err) {
|
|
1106
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1496
|
+
for (const [destination, spans] of groups) {
|
|
1497
|
+
if (!destination && !this.writeKey) continue;
|
|
1498
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1499
|
+
const opts = this.requestOpts();
|
|
1500
|
+
if (!opts) {
|
|
1107
1501
|
rateLimitedLog(
|
|
1108
|
-
`${this.prefix}.
|
|
1109
|
-
() => console.warn(
|
|
1502
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1503
|
+
() => console.warn(
|
|
1504
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1505
|
+
)
|
|
1110
1506
|
);
|
|
1507
|
+
continue;
|
|
1508
|
+
}
|
|
1509
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1510
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1511
|
+
const headers = destination ? {
|
|
1512
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1513
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1514
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1515
|
+
} : this.requestHeaders();
|
|
1516
|
+
if (this.debug) {
|
|
1517
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1518
|
+
spans: spans.length,
|
|
1519
|
+
endpoint: url
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
const p = postJson(url, body, headers, opts);
|
|
1523
|
+
this.inFlight.add(p);
|
|
1524
|
+
try {
|
|
1525
|
+
try {
|
|
1526
|
+
await p;
|
|
1527
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1530
|
+
rateLimitedLog(
|
|
1531
|
+
`${this.prefix}.send_spans_failed`,
|
|
1532
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
} finally {
|
|
1536
|
+
this.inFlight.delete(p);
|
|
1111
1537
|
}
|
|
1112
|
-
} finally {
|
|
1113
|
-
this.inFlight.delete(p);
|
|
1114
1538
|
}
|
|
1115
1539
|
}
|
|
1116
1540
|
}
|
|
@@ -1153,7 +1577,9 @@ var TraceShipper = class {
|
|
|
1153
1577
|
if (!settled) {
|
|
1154
1578
|
rateLimitedLog(
|
|
1155
1579
|
`${this.prefix}.shutdown_deadline`,
|
|
1156
|
-
() => console.warn(
|
|
1580
|
+
() => console.warn(
|
|
1581
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
1582
|
+
)
|
|
1157
1583
|
);
|
|
1158
1584
|
}
|
|
1159
1585
|
} finally {
|
|
@@ -1192,6 +1618,15 @@ function installTracingSuppressionHook() {
|
|
|
1192
1618
|
installTracingSuppressionHook();
|
|
1193
1619
|
|
|
1194
1620
|
// src/callback-handler.ts
|
|
1621
|
+
function resolveEventId(source) {
|
|
1622
|
+
if (typeof source !== "function") return randomUUID();
|
|
1623
|
+
try {
|
|
1624
|
+
const id = source();
|
|
1625
|
+
return typeof id === "string" && id.trim() !== "" ? id : randomUUID();
|
|
1626
|
+
} catch {
|
|
1627
|
+
return randomUUID();
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1195
1630
|
function isInternalName(name) {
|
|
1196
1631
|
if (name.startsWith("Branch:")) return true;
|
|
1197
1632
|
if (name.startsWith("ChannelWrite")) return true;
|
|
@@ -1240,13 +1675,15 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1240
1675
|
this.traceShipper = opts.traceShipper;
|
|
1241
1676
|
this.userId = opts.userId;
|
|
1242
1677
|
this.convoId = opts.convoId;
|
|
1678
|
+
this.eventName = opts.eventName;
|
|
1679
|
+
this.eventIdSource = opts.eventId;
|
|
1243
1680
|
this.traceChains = opts.traceChains ?? true;
|
|
1244
1681
|
}
|
|
1245
1682
|
getEventId(runId, parentRunId) {
|
|
1246
1683
|
const rootId = parentRunId ? this.rootRunIds.get(parentRunId) ?? parentRunId : runId;
|
|
1247
1684
|
this.rootRunIds.set(runId, rootId);
|
|
1248
1685
|
if (!this.eventIds.has(rootId)) {
|
|
1249
|
-
this.eventIds.set(rootId,
|
|
1686
|
+
this.eventIds.set(rootId, resolveEventId(this.eventIdSource));
|
|
1250
1687
|
}
|
|
1251
1688
|
return this.eventIds.get(rootId);
|
|
1252
1689
|
}
|
|
@@ -1275,10 +1712,11 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1275
1712
|
const eventId = this.eventIds.get(rootId);
|
|
1276
1713
|
if (!eventId) return;
|
|
1277
1714
|
if (isRoot) {
|
|
1278
|
-
if (this.convoId) {
|
|
1715
|
+
if (this.convoId || this.eventName) {
|
|
1279
1716
|
await this.eventShipper.patch(eventId, {
|
|
1280
1717
|
userId: this.userId,
|
|
1281
1718
|
convoId: this.convoId,
|
|
1719
|
+
eventName: this.eventName,
|
|
1282
1720
|
isPending: true
|
|
1283
1721
|
});
|
|
1284
1722
|
}
|
|
@@ -1287,11 +1725,16 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1287
1725
|
await this.eventShipper.patch(eventId, {
|
|
1288
1726
|
userId: this.userId,
|
|
1289
1727
|
convoId: this.convoId,
|
|
1728
|
+
eventName: this.eventName,
|
|
1290
1729
|
...patch,
|
|
1291
1730
|
isPending: true
|
|
1292
1731
|
});
|
|
1293
1732
|
}
|
|
1294
1733
|
}
|
|
1734
|
+
rootErrorPatch(runId, error) {
|
|
1735
|
+
const rootId = this.rootRunIds.get(runId) ?? runId;
|
|
1736
|
+
return rootId === runId ? { error } : void 0;
|
|
1737
|
+
}
|
|
1295
1738
|
// ---------------------------------------------------------------------------
|
|
1296
1739
|
// LLM events
|
|
1297
1740
|
// ---------------------------------------------------------------------------
|
|
@@ -1313,6 +1756,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1313
1756
|
await this.eventShipper.patch(eventId, {
|
|
1314
1757
|
userId: this.userId,
|
|
1315
1758
|
convoId: this.convoId,
|
|
1759
|
+
eventName: this.eventName,
|
|
1316
1760
|
input: truncate(prompts.join("\n"), CHAIN_TEXT_MAX_LEN),
|
|
1317
1761
|
properties: buildProperties(tags, metadata),
|
|
1318
1762
|
isPending: true
|
|
@@ -1346,6 +1790,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1346
1790
|
await this.eventShipper.patch(eventId, {
|
|
1347
1791
|
userId: this.userId,
|
|
1348
1792
|
convoId: this.convoId,
|
|
1793
|
+
eventName: this.eventName,
|
|
1349
1794
|
input: inputText,
|
|
1350
1795
|
properties: buildProperties(tags, metadata),
|
|
1351
1796
|
isPending: true
|
|
@@ -1385,8 +1830,6 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1385
1830
|
]
|
|
1386
1831
|
});
|
|
1387
1832
|
const properties = {};
|
|
1388
|
-
if (promptTokens != null) properties["ai.usage.prompt_tokens"] = promptTokens;
|
|
1389
|
-
if (completionTokens != null) properties["ai.usage.completion_tokens"] = completionTokens;
|
|
1390
1833
|
if (cachedTokens != null) properties["ai.usage.cached_tokens"] = cachedTokens;
|
|
1391
1834
|
if (reasoningTokens != null) properties["ai.usage.thoughts_tokens"] = reasoningTokens;
|
|
1392
1835
|
if (finishReason != null) properties["ai.finish_reason"] = finishReason;
|
|
@@ -1394,6 +1837,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1394
1837
|
await this.finalizeEventIfRoot(runId, {
|
|
1395
1838
|
output: cappedOutput,
|
|
1396
1839
|
model,
|
|
1840
|
+
usage: { promptTokens, completionTokens },
|
|
1397
1841
|
properties: Object.keys(properties).length > 0 ? properties : void 0
|
|
1398
1842
|
});
|
|
1399
1843
|
} catch {
|
|
@@ -1411,14 +1855,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1411
1855
|
if (span) {
|
|
1412
1856
|
this.traceShipper.endSpan(span, { error: err });
|
|
1413
1857
|
}
|
|
1414
|
-
|
|
1415
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1416
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1417
|
-
properties: {
|
|
1418
|
-
"error.type": errorInfo.type,
|
|
1419
|
-
"error.message": errorInfo.message
|
|
1420
|
-
}
|
|
1421
|
-
});
|
|
1858
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1422
1859
|
} catch {
|
|
1423
1860
|
} finally {
|
|
1424
1861
|
this.cleanup(runId);
|
|
@@ -1480,14 +1917,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1480
1917
|
const span = this.spans.get(runId);
|
|
1481
1918
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1482
1919
|
}
|
|
1483
|
-
|
|
1484
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1485
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1486
|
-
properties: {
|
|
1487
|
-
"error.type": errorInfo.type,
|
|
1488
|
-
"error.message": errorInfo.message
|
|
1489
|
-
}
|
|
1490
|
-
});
|
|
1920
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1491
1921
|
} catch {
|
|
1492
1922
|
} finally {
|
|
1493
1923
|
this.cleanup(runId);
|
|
@@ -1542,14 +1972,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1542
1972
|
try {
|
|
1543
1973
|
const span = this.spans.get(runId);
|
|
1544
1974
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1545
|
-
|
|
1546
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1547
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1548
|
-
properties: {
|
|
1549
|
-
"error.type": errorInfo.type,
|
|
1550
|
-
"error.message": errorInfo.message
|
|
1551
|
-
}
|
|
1552
|
-
});
|
|
1975
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1553
1976
|
} catch {
|
|
1554
1977
|
} finally {
|
|
1555
1978
|
this.cleanup(runId);
|
|
@@ -1714,18 +2137,6 @@ function asNumber(val) {
|
|
|
1714
2137
|
const n = typeof val === "number" ? val : Number(val);
|
|
1715
2138
|
return Number.isFinite(n) ? n : void 0;
|
|
1716
2139
|
}
|
|
1717
|
-
function extractErrorInfo(err) {
|
|
1718
|
-
if (err instanceof Error) {
|
|
1719
|
-
return { type: err.name || err.constructor.name, message: err.message };
|
|
1720
|
-
}
|
|
1721
|
-
if (typeof err === "object" && err !== null) {
|
|
1722
|
-
const e = err;
|
|
1723
|
-
const type = e.name ?? e.constructor?.name ?? "Error";
|
|
1724
|
-
const message = e.message ?? safeStringify(err);
|
|
1725
|
-
return { type, message };
|
|
1726
|
-
}
|
|
1727
|
-
return { type: "Error", message: String(err) };
|
|
1728
|
-
}
|
|
1729
2140
|
|
|
1730
2141
|
// src/version.ts
|
|
1731
2142
|
var libraryName = "@raindrop-ai/deep-agents";
|
|
@@ -1765,6 +2176,8 @@ function createRaindropDeepAgents(opts) {
|
|
|
1765
2176
|
traceShipper,
|
|
1766
2177
|
userId: opts.userId,
|
|
1767
2178
|
convoId: opts.convoId,
|
|
2179
|
+
eventName: opts.eventName,
|
|
2180
|
+
eventId: opts.eventId,
|
|
1768
2181
|
traceChains: opts.traceChains
|
|
1769
2182
|
});
|
|
1770
2183
|
return {
|