@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.mjs
CHANGED
|
@@ -1,7 +1,69 @@
|
|
|
1
1
|
// src/callback-handler.ts
|
|
2
2
|
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
3
3
|
|
|
4
|
-
// ../core/dist/chunk-
|
|
4
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
5
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
6
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
7
|
+
var EvalScopeStorage = class {
|
|
8
|
+
constructor() {
|
|
9
|
+
this._als = null;
|
|
10
|
+
this._probed = false;
|
|
11
|
+
}
|
|
12
|
+
maybeAdoptAsyncLocalStorage() {
|
|
13
|
+
if (this._probed) return;
|
|
14
|
+
this._probed = true;
|
|
15
|
+
try {
|
|
16
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
17
|
+
if (!Ctor) return;
|
|
18
|
+
const als = new Ctor();
|
|
19
|
+
als.run(PROBE_SCOPE, () => {
|
|
20
|
+
});
|
|
21
|
+
this._als = als;
|
|
22
|
+
} catch (e) {
|
|
23
|
+
this._als = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
run(scope, callback) {
|
|
27
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
28
|
+
if (this._als) return this._als.run(scope, callback);
|
|
29
|
+
const previous = this._syncScope;
|
|
30
|
+
this._syncScope = scope;
|
|
31
|
+
try {
|
|
32
|
+
return callback();
|
|
33
|
+
} finally {
|
|
34
|
+
this._syncScope = previous;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
current() {
|
|
38
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
39
|
+
if (this._als) return this._als.getStore();
|
|
40
|
+
return this._syncScope;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
44
|
+
function evalScopeStorage() {
|
|
45
|
+
const holder = globalThis;
|
|
46
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
47
|
+
if (!storage) {
|
|
48
|
+
storage = new EvalScopeStorage();
|
|
49
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
50
|
+
}
|
|
51
|
+
return storage;
|
|
52
|
+
}
|
|
53
|
+
function currentEvalScope() {
|
|
54
|
+
try {
|
|
55
|
+
return evalScopeStorage().current();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function evalScopeAttributes() {
|
|
61
|
+
const scope = currentEvalScope();
|
|
62
|
+
if (!scope) return {};
|
|
63
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ../core/dist/chunk-T53LQAH7.js
|
|
5
67
|
function getCrypto() {
|
|
6
68
|
const c = globalThis.crypto;
|
|
7
69
|
return c;
|
|
@@ -56,6 +118,39 @@ function base64Encode(bytes) {
|
|
|
56
118
|
}
|
|
57
119
|
return out;
|
|
58
120
|
}
|
|
121
|
+
function base64ToHex(value) {
|
|
122
|
+
if (!value) return "";
|
|
123
|
+
const maybeBuffer = globalThis.Buffer;
|
|
124
|
+
if (maybeBuffer) {
|
|
125
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
126
|
+
}
|
|
127
|
+
const atobFn = globalThis.atob;
|
|
128
|
+
if (typeof atobFn !== "function") return "";
|
|
129
|
+
try {
|
|
130
|
+
const binary = atobFn(value);
|
|
131
|
+
let hex = "";
|
|
132
|
+
for (let i = 0; i < binary.length; i++) {
|
|
133
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
134
|
+
}
|
|
135
|
+
return hex;
|
|
136
|
+
} catch (e) {
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
141
|
+
mode: "raindrop.handoff.mode",
|
|
142
|
+
childEventId: "raindrop.handoff.childEventId",
|
|
143
|
+
parentEventId: "raindrop.handoff.parentEventId",
|
|
144
|
+
parentSpanId: "raindrop.handoff.parentSpanId",
|
|
145
|
+
name: "raindrop.handoff.name",
|
|
146
|
+
terminal: "raindrop.handoff.terminal",
|
|
147
|
+
agentRole: "raindrop.agent.role"
|
|
148
|
+
};
|
|
149
|
+
var HANDOFF_TERMINAL_PROPERTY_KEY = HANDOFF_ATTRIBUTE_SUFFIXES.terminal;
|
|
150
|
+
var TRACEPARENT_HEADER = "traceparent";
|
|
151
|
+
var BAGGAGE_HEADER = "baggage";
|
|
152
|
+
var HANDOFF_HEADER = "x-raindrop-handoff";
|
|
153
|
+
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.`;
|
|
59
154
|
function runWithTracingSuppressed(fn) {
|
|
60
155
|
const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
|
|
61
156
|
if (typeof hook !== "function") return fn();
|
|
@@ -183,6 +278,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
183
278
|
const resp = await runWithTracingSuppressed(
|
|
184
279
|
() => fetch(url, {
|
|
185
280
|
method: "POST",
|
|
281
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
186
282
|
headers: {
|
|
187
283
|
"Content-Type": "application/json",
|
|
188
284
|
...headers
|
|
@@ -284,6 +380,55 @@ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", se
|
|
|
284
380
|
]
|
|
285
381
|
};
|
|
286
382
|
}
|
|
383
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
384
|
+
function state() {
|
|
385
|
+
const holder = globalThis;
|
|
386
|
+
let current = holder[STATE_KEY];
|
|
387
|
+
if (!current) {
|
|
388
|
+
let storage = null;
|
|
389
|
+
try {
|
|
390
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
391
|
+
if (Ctor) storage = new Ctor();
|
|
392
|
+
} catch (e) {
|
|
393
|
+
storage = null;
|
|
394
|
+
}
|
|
395
|
+
current = {
|
|
396
|
+
storage,
|
|
397
|
+
syncDestination: void 0,
|
|
398
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
399
|
+
};
|
|
400
|
+
holder[STATE_KEY] = current;
|
|
401
|
+
}
|
|
402
|
+
return current;
|
|
403
|
+
}
|
|
404
|
+
function currentReplayTraceDestination() {
|
|
405
|
+
var _a, _b;
|
|
406
|
+
const routing = state();
|
|
407
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
408
|
+
}
|
|
409
|
+
function rememberReplayTraceDestination(span) {
|
|
410
|
+
const destination = currentReplayTraceDestination();
|
|
411
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
412
|
+
}
|
|
413
|
+
function copyReplayTraceDestination(source, target) {
|
|
414
|
+
const destination = state().spanDestinations.get(source);
|
|
415
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
416
|
+
}
|
|
417
|
+
function replayTraceDestinationFor(value) {
|
|
418
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
419
|
+
return void 0;
|
|
420
|
+
}
|
|
421
|
+
return state().spanDestinations.get(value);
|
|
422
|
+
}
|
|
423
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
424
|
+
var _a, _b;
|
|
425
|
+
if (!destination || !spanId || !traceId) return;
|
|
426
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
427
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
428
|
+
}
|
|
429
|
+
function replayTraceUrl(baseUrl) {
|
|
430
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
431
|
+
}
|
|
287
432
|
var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
|
|
288
433
|
var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
|
|
289
434
|
var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
|
|
@@ -346,26 +491,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
346
491
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
347
492
|
return null;
|
|
348
493
|
}
|
|
494
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
349
495
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
350
496
|
var _a;
|
|
351
497
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
352
|
-
if (!baseUrl) return;
|
|
353
|
-
|
|
498
|
+
if (!baseUrl) return Promise.resolve();
|
|
499
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
354
500
|
maxAttempts: 1,
|
|
355
501
|
debug: (_a = options.debug) != null ? _a : false,
|
|
356
|
-
sdkName: options.sdkName
|
|
502
|
+
sdkName: options.sdkName,
|
|
503
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
357
504
|
}).catch(() => {
|
|
358
505
|
});
|
|
359
506
|
}
|
|
360
507
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
361
508
|
var _a;
|
|
362
509
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
363
|
-
if (!baseUrl) return;
|
|
510
|
+
if (!baseUrl) return Promise.resolve();
|
|
364
511
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
365
|
-
|
|
512
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
366
513
|
maxAttempts: 1,
|
|
367
514
|
debug: (_a = options.debug) != null ? _a : false,
|
|
368
|
-
sdkName: options.sdkName
|
|
515
|
+
sdkName: options.sdkName,
|
|
516
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
369
517
|
}).catch(() => {
|
|
370
518
|
});
|
|
371
519
|
}
|
|
@@ -391,16 +539,52 @@ function projectIdHeaders(projectId) {
|
|
|
391
539
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
392
540
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
393
541
|
function mergePatches(target, source) {
|
|
394
|
-
var _a, _b, _c, _d;
|
|
542
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
395
543
|
const out = { ...target, ...source };
|
|
396
544
|
if (target.properties || source.properties) {
|
|
397
545
|
out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
|
|
398
546
|
}
|
|
547
|
+
if (target.usage || source.usage) {
|
|
548
|
+
out.usage = { ...(_c = target.usage) != null ? _c : {} };
|
|
549
|
+
if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
|
|
550
|
+
out.usage.promptTokens = source.usage.promptTokens;
|
|
551
|
+
}
|
|
552
|
+
if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
|
|
553
|
+
out.usage.completionTokens = source.usage.completionTokens;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (source.error === void 0) {
|
|
557
|
+
out.error = target.error;
|
|
558
|
+
}
|
|
559
|
+
if (target.featureFlags || source.featureFlags) {
|
|
560
|
+
out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
|
|
561
|
+
}
|
|
399
562
|
if (target.attachments || source.attachments) {
|
|
400
|
-
out.attachments = [...(
|
|
563
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
401
564
|
}
|
|
402
565
|
return out;
|
|
403
566
|
}
|
|
567
|
+
function isErrorLike(value) {
|
|
568
|
+
return value !== null && typeof value === "object";
|
|
569
|
+
}
|
|
570
|
+
function eventTelemetryProperties(patch) {
|
|
571
|
+
var _a, _b;
|
|
572
|
+
const properties = {};
|
|
573
|
+
if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
|
|
574
|
+
properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
|
|
575
|
+
}
|
|
576
|
+
if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
|
|
577
|
+
properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
|
|
578
|
+
}
|
|
579
|
+
if (patch.error !== void 0 && patch.error !== null) {
|
|
580
|
+
const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
|
|
581
|
+
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";
|
|
582
|
+
const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
|
|
583
|
+
properties["error.type"] = errorType;
|
|
584
|
+
properties["error.message"] = errorMessage;
|
|
585
|
+
}
|
|
586
|
+
return properties;
|
|
587
|
+
}
|
|
404
588
|
var EventShipper = class {
|
|
405
589
|
constructor(opts) {
|
|
406
590
|
this.buffers = /* @__PURE__ */ new Map();
|
|
@@ -486,6 +670,15 @@ var EventShipper = class {
|
|
|
486
670
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
487
671
|
if (!this.enabled) return;
|
|
488
672
|
if (!eventId || !eventId.trim()) return;
|
|
673
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
674
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
675
|
+
const destination = currentReplayTraceDestination();
|
|
676
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
677
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
678
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
679
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
489
682
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
490
683
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
491
684
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -544,6 +737,9 @@ var EventShipper = class {
|
|
|
544
737
|
try {
|
|
545
738
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
546
739
|
this.timers.clear();
|
|
740
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
741
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
742
|
+
}
|
|
547
743
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
548
744
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
549
745
|
} finally {
|
|
@@ -553,6 +749,8 @@ var EventShipper = class {
|
|
|
553
749
|
async trackSignal(signal) {
|
|
554
750
|
var _a, _b;
|
|
555
751
|
if (!this.enabled) return;
|
|
752
|
+
const destination = currentReplayTraceDestination();
|
|
753
|
+
if (destination && destination.kind !== "workshop") return;
|
|
556
754
|
const body = [
|
|
557
755
|
{
|
|
558
756
|
event_id: signal.eventId,
|
|
@@ -587,6 +785,8 @@ var EventShipper = class {
|
|
|
587
785
|
}
|
|
588
786
|
async identify(users) {
|
|
589
787
|
if (!this.enabled) return;
|
|
788
|
+
const destination = currentReplayTraceDestination();
|
|
789
|
+
if (destination && destination.kind !== "workshop") return;
|
|
590
790
|
const list = Array.isArray(users) ? users : [users];
|
|
591
791
|
const body = list.filter((user) => {
|
|
592
792
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -639,8 +839,9 @@ var EventShipper = class {
|
|
|
639
839
|
this.buffers.delete(eventId);
|
|
640
840
|
if (!accumulated) return;
|
|
641
841
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
642
|
-
const
|
|
643
|
-
const
|
|
842
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
843
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
844
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
644
845
|
if (!userId) {
|
|
645
846
|
if (this.debug) {
|
|
646
847
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -648,9 +849,13 @@ var EventShipper = class {
|
|
|
648
849
|
this.sticky.delete(eventId);
|
|
649
850
|
return;
|
|
650
851
|
}
|
|
651
|
-
const { wizardSession, ...restProperties } = (
|
|
652
|
-
|
|
653
|
-
|
|
852
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
853
|
+
let telemetryProperties = {};
|
|
854
|
+
try {
|
|
855
|
+
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
856
|
+
} catch (e) {
|
|
857
|
+
}
|
|
858
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
654
859
|
const payload = {
|
|
655
860
|
event_id: eventId,
|
|
656
861
|
user_id: userId,
|
|
@@ -658,15 +863,17 @@ var EventShipper = class {
|
|
|
658
863
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
659
864
|
ai_data: {
|
|
660
865
|
input: accumulated.input,
|
|
661
|
-
output: accumulated.output,
|
|
866
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
662
867
|
model: accumulated.model,
|
|
663
868
|
convo_id: convoId
|
|
664
869
|
},
|
|
665
870
|
properties: {
|
|
666
871
|
...restProperties,
|
|
872
|
+
...telemetryProperties,
|
|
667
873
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
668
874
|
$context: this.context
|
|
669
875
|
},
|
|
876
|
+
...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
|
|
670
877
|
attachments: accumulated.attachments,
|
|
671
878
|
is_pending: isPending
|
|
672
879
|
};
|
|
@@ -690,29 +897,30 @@ var EventShipper = class {
|
|
|
690
897
|
endpoint: url
|
|
691
898
|
});
|
|
692
899
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
});
|
|
700
|
-
}
|
|
900
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
901
|
+
baseUrl: this.localDebuggerUrl,
|
|
902
|
+
writeKey: this.writeKey,
|
|
903
|
+
debug: this.debug,
|
|
904
|
+
sdkName: this.sdkName
|
|
905
|
+
}) : void 0;
|
|
701
906
|
if (!this.writeKey) {
|
|
702
907
|
if (!isPending) this.sticky.delete(eventId);
|
|
908
|
+
if (mirror) await mirror;
|
|
703
909
|
return;
|
|
704
910
|
}
|
|
705
911
|
const opts = this.requestOpts();
|
|
706
912
|
if (!opts) {
|
|
707
913
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
708
914
|
if (!isPending) this.sticky.delete(eventId);
|
|
915
|
+
if (mirror) await mirror;
|
|
709
916
|
return;
|
|
710
917
|
}
|
|
711
918
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
712
|
-
|
|
919
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
920
|
+
this.inFlight.add(combined);
|
|
713
921
|
try {
|
|
714
922
|
try {
|
|
715
|
-
await
|
|
923
|
+
await combined;
|
|
716
924
|
if (this.debug) {
|
|
717
925
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
718
926
|
}
|
|
@@ -724,13 +932,156 @@ var EventShipper = class {
|
|
|
724
932
|
);
|
|
725
933
|
}
|
|
726
934
|
} finally {
|
|
727
|
-
this.inFlight.delete(
|
|
935
|
+
this.inFlight.delete(combined);
|
|
728
936
|
}
|
|
729
937
|
if (!isPending) {
|
|
730
938
|
this.sticky.delete(eventId);
|
|
731
939
|
}
|
|
732
940
|
}
|
|
733
941
|
};
|
|
942
|
+
var MODEL_USAGE_ATTRIBUTES = {
|
|
943
|
+
usageSource: "raindrop.usage.source",
|
|
944
|
+
providerName: "gen_ai.provider.name",
|
|
945
|
+
requestModel: "gen_ai.request.model",
|
|
946
|
+
responseModel: "gen_ai.response.model",
|
|
947
|
+
inputTokens: "gen_ai.usage.input_tokens",
|
|
948
|
+
outputTokens: "gen_ai.usage.output_tokens",
|
|
949
|
+
reasoningTokens: "gen_ai.usage.reasoning_tokens",
|
|
950
|
+
cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
|
|
951
|
+
cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
|
|
952
|
+
providerReportedCost: "gen_ai.usage.provider_reported_cost",
|
|
953
|
+
nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
|
|
954
|
+
nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
|
|
955
|
+
totalOutputTokens: "raindrop.usage.output_tokens.total",
|
|
956
|
+
reasoningOutputTokens: "raindrop.usage.output_tokens.reasoning",
|
|
957
|
+
cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
|
|
958
|
+
cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
|
|
959
|
+
};
|
|
960
|
+
var MODEL_PROVIDER_NAMES = [
|
|
961
|
+
["google.vertex.anthropic", "google-vertex"],
|
|
962
|
+
["google.vertex_ai", "google-vertex"],
|
|
963
|
+
["google.vertex", "google-vertex"],
|
|
964
|
+
["gcp.vertex_ai", "google-vertex"],
|
|
965
|
+
["gcp.gemini", "google"],
|
|
966
|
+
["google_vertexai", "google-vertex"],
|
|
967
|
+
["vertex.anthropic", "google-vertex"],
|
|
968
|
+
["amazon-bedrock", "amazon-bedrock"],
|
|
969
|
+
["aws.bedrock", "amazon-bedrock"],
|
|
970
|
+
["bedrock", "amazon-bedrock"],
|
|
971
|
+
["anthropic", "anthropic"],
|
|
972
|
+
["openai", "openai"],
|
|
973
|
+
["google", "google"],
|
|
974
|
+
["az.ai.openai", "azure"],
|
|
975
|
+
["azure", "azure"],
|
|
976
|
+
["openrouter", "openrouter"]
|
|
977
|
+
];
|
|
978
|
+
function canonicalModelProvider(provider) {
|
|
979
|
+
var _a;
|
|
980
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
981
|
+
if (normalizedProvider === "gateway") return "vercel";
|
|
982
|
+
const match = MODEL_PROVIDER_NAMES.find(
|
|
983
|
+
([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
|
|
984
|
+
);
|
|
985
|
+
return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
|
|
986
|
+
}
|
|
987
|
+
var STRING_ALIASES = {
|
|
988
|
+
[MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
|
|
989
|
+
};
|
|
990
|
+
var NUMBER_ALIASES = {
|
|
991
|
+
[MODEL_USAGE_ATTRIBUTES.inputTokens]: [
|
|
992
|
+
"gen_ai.usage.prompt_tokens",
|
|
993
|
+
"ai.usage.prompt_tokens",
|
|
994
|
+
"ai.usage.promptTokens",
|
|
995
|
+
"ai.usage.input_tokens",
|
|
996
|
+
"ai.usage.inputTokens"
|
|
997
|
+
],
|
|
998
|
+
[MODEL_USAGE_ATTRIBUTES.outputTokens]: [
|
|
999
|
+
"gen_ai.usage.completion_tokens",
|
|
1000
|
+
"ai.usage.completion_tokens",
|
|
1001
|
+
"ai.usage.completionTokens",
|
|
1002
|
+
"ai.usage.output_tokens",
|
|
1003
|
+
"ai.usage.outputTokens"
|
|
1004
|
+
],
|
|
1005
|
+
[MODEL_USAGE_ATTRIBUTES.reasoningTokens]: [
|
|
1006
|
+
"gen_ai.usage.reasoning.output_tokens",
|
|
1007
|
+
"ai.usage.reasoningTokens",
|
|
1008
|
+
"ai.usage.thoughts_tokens"
|
|
1009
|
+
],
|
|
1010
|
+
[MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens]: [
|
|
1011
|
+
"gen_ai.usage.cache_read_tokens",
|
|
1012
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
1013
|
+
"ai.usage.cachedInputTokens",
|
|
1014
|
+
"ai.usage.cached_tokens",
|
|
1015
|
+
"ai.usage.cache_read_tokens",
|
|
1016
|
+
"ai.usage.cache_read_input_tokens",
|
|
1017
|
+
"ai.usage.cacheReadInputTokens"
|
|
1018
|
+
],
|
|
1019
|
+
[MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens]: [
|
|
1020
|
+
"gen_ai.usage.cache_creation_input_tokens",
|
|
1021
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
1022
|
+
"ai.usage.cacheWriteInputTokens",
|
|
1023
|
+
"ai.usage.cache_creation_input_tokens",
|
|
1024
|
+
"ai.usage.cacheCreationInputTokens"
|
|
1025
|
+
]
|
|
1026
|
+
};
|
|
1027
|
+
function hasAttribute(attributes, key) {
|
|
1028
|
+
return attributes.some((attribute) => attribute.key === key);
|
|
1029
|
+
}
|
|
1030
|
+
function findStringAttribute(attributes, keys) {
|
|
1031
|
+
return attributes.find(
|
|
1032
|
+
(attribute) => keys.includes(attribute.key) && typeof attribute.value.stringValue === "string" && attribute.value.stringValue.length > 0
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
function findNumberAttribute(attributes, keys) {
|
|
1036
|
+
return attributes.find((attribute) => {
|
|
1037
|
+
if (!keys.includes(attribute.key)) return false;
|
|
1038
|
+
if (typeof attribute.value.doubleValue === "number" && Number.isSafeInteger(attribute.value.doubleValue) && attribute.value.doubleValue >= 0) {
|
|
1039
|
+
return true;
|
|
1040
|
+
}
|
|
1041
|
+
const intValue = attribute.value.intValue;
|
|
1042
|
+
return integerValue(intValue) !== void 0;
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
function integerValue(value) {
|
|
1046
|
+
if (typeof value === "number") {
|
|
1047
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
1048
|
+
}
|
|
1049
|
+
if (typeof value !== "string") return void 0;
|
|
1050
|
+
const parsed = Number(value);
|
|
1051
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
1052
|
+
}
|
|
1053
|
+
function appendAlias(attributes, target, source) {
|
|
1054
|
+
if (!source || hasAttribute(attributes, target)) return attributes;
|
|
1055
|
+
return [...attributes, { key: target, value: { ...source.value } }];
|
|
1056
|
+
}
|
|
1057
|
+
function appendProviderAlias(attributes) {
|
|
1058
|
+
if (hasAttribute(attributes, MODEL_USAGE_ATTRIBUTES.providerName)) return attributes;
|
|
1059
|
+
const source = findStringAttribute(attributes, ["gen_ai.system", "ai.model.provider"]);
|
|
1060
|
+
if (!(source == null ? void 0 : source.value.stringValue)) return attributes;
|
|
1061
|
+
const attribute = attrString(
|
|
1062
|
+
MODEL_USAGE_ATTRIBUTES.providerName,
|
|
1063
|
+
canonicalModelProvider(source.value.stringValue)
|
|
1064
|
+
);
|
|
1065
|
+
return attribute ? [...attributes, attribute] : attributes;
|
|
1066
|
+
}
|
|
1067
|
+
function normalizeModelUsageSpan(span) {
|
|
1068
|
+
const original = span.attributes;
|
|
1069
|
+
if (!original || original.length === 0) return span;
|
|
1070
|
+
const responseModel = findStringAttribute(original, [
|
|
1071
|
+
MODEL_USAGE_ATTRIBUTES.responseModel,
|
|
1072
|
+
"ai.response.model"
|
|
1073
|
+
]);
|
|
1074
|
+
if (!responseModel) return span;
|
|
1075
|
+
let attributes = appendAlias(original, MODEL_USAGE_ATTRIBUTES.responseModel, responseModel);
|
|
1076
|
+
attributes = appendProviderAlias(attributes);
|
|
1077
|
+
for (const [target, aliases] of Object.entries(STRING_ALIASES)) {
|
|
1078
|
+
attributes = appendAlias(attributes, target, findStringAttribute(attributes, aliases));
|
|
1079
|
+
}
|
|
1080
|
+
for (const [target, aliases] of Object.entries(NUMBER_ALIASES)) {
|
|
1081
|
+
attributes = appendAlias(attributes, target, findNumberAttribute(attributes, aliases));
|
|
1082
|
+
}
|
|
1083
|
+
return attributes === original ? span : { ...span, attributes };
|
|
1084
|
+
}
|
|
734
1085
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
735
1086
|
"apikey",
|
|
736
1087
|
"apisecret",
|
|
@@ -820,6 +1171,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
820
1171
|
if (scrubbedJson === json) return void 0;
|
|
821
1172
|
return { stringValue: scrubbedJson };
|
|
822
1173
|
}
|
|
1174
|
+
function identityAttrs(args) {
|
|
1175
|
+
return [
|
|
1176
|
+
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
1177
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
|
|
1178
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
|
|
1179
|
+
];
|
|
1180
|
+
}
|
|
823
1181
|
function applyOtelSpanAttributeLimit(limit) {
|
|
824
1182
|
var _a, _b;
|
|
825
1183
|
try {
|
|
@@ -915,7 +1273,10 @@ var TraceShipper = class {
|
|
|
915
1273
|
try {
|
|
916
1274
|
const result = this.transformSpanHook(current);
|
|
917
1275
|
if (result === null) return null;
|
|
918
|
-
if (result !== void 0)
|
|
1276
|
+
if (result !== void 0) {
|
|
1277
|
+
copyReplayTraceDestination(current, result);
|
|
1278
|
+
current = result;
|
|
1279
|
+
}
|
|
919
1280
|
} catch (err) {
|
|
920
1281
|
if (this.debug) {
|
|
921
1282
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -924,10 +1285,20 @@ var TraceShipper = class {
|
|
|
924
1285
|
return null;
|
|
925
1286
|
}
|
|
926
1287
|
}
|
|
1288
|
+
try {
|
|
1289
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1290
|
+
copyReplayTraceDestination(current, normalized);
|
|
1291
|
+
current = normalized;
|
|
1292
|
+
} catch (e) {
|
|
1293
|
+
}
|
|
927
1294
|
if (!this.disableDefaultRedaction) {
|
|
928
|
-
|
|
1295
|
+
const redacted = defaultTransformSpan(current);
|
|
1296
|
+
copyReplayTraceDestination(current, redacted);
|
|
1297
|
+
current = redacted;
|
|
929
1298
|
}
|
|
930
|
-
|
|
1299
|
+
const capped = this.capSpanAttributes(current);
|
|
1300
|
+
copyReplayTraceDestination(current, capped);
|
|
1301
|
+
return capped;
|
|
931
1302
|
}
|
|
932
1303
|
isDebugEnabled() {
|
|
933
1304
|
return this.debug;
|
|
@@ -944,33 +1315,55 @@ var TraceShipper = class {
|
|
|
944
1315
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
945
1316
|
const attrs = [
|
|
946
1317
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
947
|
-
|
|
1318
|
+
...identityAttrs(args),
|
|
1319
|
+
attrString("ai.operationId", args.operationId),
|
|
1320
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
948
1321
|
];
|
|
949
1322
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
950
|
-
const span = {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1323
|
+
const span = {
|
|
1324
|
+
ids,
|
|
1325
|
+
name: args.name,
|
|
1326
|
+
startTimeUnixNano: started,
|
|
1327
|
+
attributes: attrs
|
|
1328
|
+
};
|
|
1329
|
+
rememberReplayTraceDestination(span);
|
|
1330
|
+
const openSpan = buildOtlpSpan({
|
|
1331
|
+
ids: span.ids,
|
|
1332
|
+
name: span.name,
|
|
1333
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1334
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1335
|
+
// placeholder — will be updated on endSpan
|
|
1336
|
+
attributes: span.attributes,
|
|
1337
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1338
|
+
});
|
|
1339
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1340
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
962
1341
|
return span;
|
|
963
1342
|
}
|
|
964
|
-
mirrorToLocalDebugger(span) {
|
|
965
|
-
|
|
1343
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1344
|
+
const destination = replayTraceDestinationFor(span);
|
|
1345
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1346
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1347
|
+
if (!localDebuggerUrl) return;
|
|
966
1348
|
const redacted = this.redactSpan(span);
|
|
967
1349
|
if (redacted === null) return;
|
|
1350
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1351
|
+
recordReplayExportedSpan(
|
|
1352
|
+
destination,
|
|
1353
|
+
base64ToHex(redacted.spanId),
|
|
1354
|
+
base64ToHex(redacted.traceId)
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
968
1357
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
969
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
970
|
-
baseUrl:
|
|
1358
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1359
|
+
baseUrl: localDebuggerUrl,
|
|
971
1360
|
debug: false,
|
|
972
1361
|
sdkName: this.sdkName
|
|
973
1362
|
});
|
|
1363
|
+
this.inFlight.add(p);
|
|
1364
|
+
void p.finally(() => {
|
|
1365
|
+
this.inFlight.delete(p);
|
|
1366
|
+
});
|
|
974
1367
|
}
|
|
975
1368
|
endSpan(span, extra) {
|
|
976
1369
|
var _a, _b;
|
|
@@ -992,14 +1385,17 @@ var TraceShipper = class {
|
|
|
992
1385
|
attributes: span.attributes,
|
|
993
1386
|
status
|
|
994
1387
|
});
|
|
1388
|
+
copyReplayTraceDestination(span, otlp);
|
|
995
1389
|
this.enqueue(otlp);
|
|
996
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1390
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
997
1391
|
}
|
|
998
1392
|
createSpan(args) {
|
|
999
1393
|
var _a;
|
|
1000
1394
|
const ids = createSpanIds(args.parent);
|
|
1001
1395
|
const attrs = [
|
|
1002
|
-
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
|
|
1396
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1397
|
+
...identityAttrs(args),
|
|
1398
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1003
1399
|
];
|
|
1004
1400
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1005
1401
|
const otlp = buildOtlpSpan({
|
|
@@ -1010,8 +1406,9 @@ var TraceShipper = class {
|
|
|
1010
1406
|
attributes: attrs,
|
|
1011
1407
|
status: args.status
|
|
1012
1408
|
});
|
|
1409
|
+
rememberReplayTraceDestination(otlp);
|
|
1013
1410
|
this.enqueue(otlp);
|
|
1014
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1411
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1015
1412
|
}
|
|
1016
1413
|
enqueue(span) {
|
|
1017
1414
|
if (!this.enabled) return;
|
|
@@ -1025,6 +1422,13 @@ var TraceShipper = class {
|
|
|
1025
1422
|
}
|
|
1026
1423
|
const redacted = this.redactSpan(span);
|
|
1027
1424
|
if (redacted === null) return;
|
|
1425
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1426
|
+
recordReplayExportedSpan(
|
|
1427
|
+
destination,
|
|
1428
|
+
base64ToHex(redacted.spanId),
|
|
1429
|
+
base64ToHex(redacted.traceId)
|
|
1430
|
+
);
|
|
1431
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1028
1432
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1029
1433
|
this.queue.shift();
|
|
1030
1434
|
}
|
|
@@ -1043,47 +1447,67 @@ var TraceShipper = class {
|
|
|
1043
1447
|
}
|
|
1044
1448
|
}
|
|
1045
1449
|
async flush() {
|
|
1046
|
-
|
|
1450
|
+
var _a;
|
|
1451
|
+
if (!this.enabled) {
|
|
1452
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1453
|
+
})));
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1047
1456
|
if (this.timer) {
|
|
1048
1457
|
clearTimeout(this.timer);
|
|
1049
1458
|
this.timer = void 0;
|
|
1050
1459
|
}
|
|
1051
1460
|
while (this.queue.length > 0) {
|
|
1052
1461
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1053
|
-
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1060
|
-
)
|
|
1061
|
-
);
|
|
1062
|
-
continue;
|
|
1063
|
-
}
|
|
1064
|
-
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
1065
|
-
const url = `${this.baseUrl}traces`;
|
|
1066
|
-
if (this.debug) {
|
|
1067
|
-
console.log(`${this.prefix} sending traces batch`, {
|
|
1068
|
-
spans: batch.length,
|
|
1069
|
-
endpoint: url
|
|
1070
|
-
});
|
|
1462
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1463
|
+
for (const span of batch) {
|
|
1464
|
+
const destination = replayTraceDestinationFor(span);
|
|
1465
|
+
const spans = groups.get(destination);
|
|
1466
|
+
if (spans) spans.push(span);
|
|
1467
|
+
else groups.set(destination, [span]);
|
|
1071
1468
|
}
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1078
|
-
} catch (err) {
|
|
1079
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1469
|
+
for (const [destination, spans] of groups) {
|
|
1470
|
+
if (!destination && !this.writeKey) continue;
|
|
1471
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1472
|
+
const opts = this.requestOpts();
|
|
1473
|
+
if (!opts) {
|
|
1080
1474
|
rateLimitedLog(
|
|
1081
|
-
`${this.prefix}.
|
|
1082
|
-
() => console.warn(
|
|
1475
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1476
|
+
() => console.warn(
|
|
1477
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1478
|
+
)
|
|
1083
1479
|
);
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1483
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1484
|
+
const headers = destination ? {
|
|
1485
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1486
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1487
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1488
|
+
} : this.requestHeaders();
|
|
1489
|
+
if (this.debug) {
|
|
1490
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1491
|
+
spans: spans.length,
|
|
1492
|
+
endpoint: url
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
const p = postJson(url, body, headers, opts);
|
|
1496
|
+
this.inFlight.add(p);
|
|
1497
|
+
try {
|
|
1498
|
+
try {
|
|
1499
|
+
await p;
|
|
1500
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
1501
|
+
} catch (err) {
|
|
1502
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1503
|
+
rateLimitedLog(
|
|
1504
|
+
`${this.prefix}.send_spans_failed`,
|
|
1505
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
} finally {
|
|
1509
|
+
this.inFlight.delete(p);
|
|
1084
1510
|
}
|
|
1085
|
-
} finally {
|
|
1086
|
-
this.inFlight.delete(p);
|
|
1087
1511
|
}
|
|
1088
1512
|
}
|
|
1089
1513
|
}
|
|
@@ -1126,7 +1550,9 @@ var TraceShipper = class {
|
|
|
1126
1550
|
if (!settled) {
|
|
1127
1551
|
rateLimitedLog(
|
|
1128
1552
|
`${this.prefix}.shutdown_deadline`,
|
|
1129
|
-
() => console.warn(
|
|
1553
|
+
() => console.warn(
|
|
1554
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
1555
|
+
)
|
|
1130
1556
|
);
|
|
1131
1557
|
}
|
|
1132
1558
|
} finally {
|
|
@@ -1165,6 +1591,15 @@ function installTracingSuppressionHook() {
|
|
|
1165
1591
|
installTracingSuppressionHook();
|
|
1166
1592
|
|
|
1167
1593
|
// src/callback-handler.ts
|
|
1594
|
+
function resolveEventId(source) {
|
|
1595
|
+
if (typeof source !== "function") return randomUUID();
|
|
1596
|
+
try {
|
|
1597
|
+
const id = source();
|
|
1598
|
+
return typeof id === "string" && id.trim() !== "" ? id : randomUUID();
|
|
1599
|
+
} catch {
|
|
1600
|
+
return randomUUID();
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1168
1603
|
function isInternalName(name) {
|
|
1169
1604
|
if (name.startsWith("Branch:")) return true;
|
|
1170
1605
|
if (name.startsWith("ChannelWrite")) return true;
|
|
@@ -1213,13 +1648,15 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1213
1648
|
this.traceShipper = opts.traceShipper;
|
|
1214
1649
|
this.userId = opts.userId;
|
|
1215
1650
|
this.convoId = opts.convoId;
|
|
1651
|
+
this.eventName = opts.eventName;
|
|
1652
|
+
this.eventIdSource = opts.eventId;
|
|
1216
1653
|
this.traceChains = opts.traceChains ?? true;
|
|
1217
1654
|
}
|
|
1218
1655
|
getEventId(runId, parentRunId) {
|
|
1219
1656
|
const rootId = parentRunId ? this.rootRunIds.get(parentRunId) ?? parentRunId : runId;
|
|
1220
1657
|
this.rootRunIds.set(runId, rootId);
|
|
1221
1658
|
if (!this.eventIds.has(rootId)) {
|
|
1222
|
-
this.eventIds.set(rootId,
|
|
1659
|
+
this.eventIds.set(rootId, resolveEventId(this.eventIdSource));
|
|
1223
1660
|
}
|
|
1224
1661
|
return this.eventIds.get(rootId);
|
|
1225
1662
|
}
|
|
@@ -1248,10 +1685,11 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1248
1685
|
const eventId = this.eventIds.get(rootId);
|
|
1249
1686
|
if (!eventId) return;
|
|
1250
1687
|
if (isRoot) {
|
|
1251
|
-
if (this.convoId) {
|
|
1688
|
+
if (this.convoId || this.eventName) {
|
|
1252
1689
|
await this.eventShipper.patch(eventId, {
|
|
1253
1690
|
userId: this.userId,
|
|
1254
1691
|
convoId: this.convoId,
|
|
1692
|
+
eventName: this.eventName,
|
|
1255
1693
|
isPending: true
|
|
1256
1694
|
});
|
|
1257
1695
|
}
|
|
@@ -1260,11 +1698,16 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1260
1698
|
await this.eventShipper.patch(eventId, {
|
|
1261
1699
|
userId: this.userId,
|
|
1262
1700
|
convoId: this.convoId,
|
|
1701
|
+
eventName: this.eventName,
|
|
1263
1702
|
...patch,
|
|
1264
1703
|
isPending: true
|
|
1265
1704
|
});
|
|
1266
1705
|
}
|
|
1267
1706
|
}
|
|
1707
|
+
rootErrorPatch(runId, error) {
|
|
1708
|
+
const rootId = this.rootRunIds.get(runId) ?? runId;
|
|
1709
|
+
return rootId === runId ? { error } : void 0;
|
|
1710
|
+
}
|
|
1268
1711
|
// ---------------------------------------------------------------------------
|
|
1269
1712
|
// LLM events
|
|
1270
1713
|
// ---------------------------------------------------------------------------
|
|
@@ -1286,6 +1729,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1286
1729
|
await this.eventShipper.patch(eventId, {
|
|
1287
1730
|
userId: this.userId,
|
|
1288
1731
|
convoId: this.convoId,
|
|
1732
|
+
eventName: this.eventName,
|
|
1289
1733
|
input: truncate(prompts.join("\n"), CHAIN_TEXT_MAX_LEN),
|
|
1290
1734
|
properties: buildProperties(tags, metadata),
|
|
1291
1735
|
isPending: true
|
|
@@ -1319,6 +1763,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1319
1763
|
await this.eventShipper.patch(eventId, {
|
|
1320
1764
|
userId: this.userId,
|
|
1321
1765
|
convoId: this.convoId,
|
|
1766
|
+
eventName: this.eventName,
|
|
1322
1767
|
input: inputText,
|
|
1323
1768
|
properties: buildProperties(tags, metadata),
|
|
1324
1769
|
isPending: true
|
|
@@ -1358,8 +1803,6 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1358
1803
|
]
|
|
1359
1804
|
});
|
|
1360
1805
|
const properties = {};
|
|
1361
|
-
if (promptTokens != null) properties["ai.usage.prompt_tokens"] = promptTokens;
|
|
1362
|
-
if (completionTokens != null) properties["ai.usage.completion_tokens"] = completionTokens;
|
|
1363
1806
|
if (cachedTokens != null) properties["ai.usage.cached_tokens"] = cachedTokens;
|
|
1364
1807
|
if (reasoningTokens != null) properties["ai.usage.thoughts_tokens"] = reasoningTokens;
|
|
1365
1808
|
if (finishReason != null) properties["ai.finish_reason"] = finishReason;
|
|
@@ -1367,6 +1810,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1367
1810
|
await this.finalizeEventIfRoot(runId, {
|
|
1368
1811
|
output: cappedOutput,
|
|
1369
1812
|
model,
|
|
1813
|
+
usage: { promptTokens, completionTokens },
|
|
1370
1814
|
properties: Object.keys(properties).length > 0 ? properties : void 0
|
|
1371
1815
|
});
|
|
1372
1816
|
} catch {
|
|
@@ -1384,14 +1828,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1384
1828
|
if (span) {
|
|
1385
1829
|
this.traceShipper.endSpan(span, { error: err });
|
|
1386
1830
|
}
|
|
1387
|
-
|
|
1388
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1389
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1390
|
-
properties: {
|
|
1391
|
-
"error.type": errorInfo.type,
|
|
1392
|
-
"error.message": errorInfo.message
|
|
1393
|
-
}
|
|
1394
|
-
});
|
|
1831
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1395
1832
|
} catch {
|
|
1396
1833
|
} finally {
|
|
1397
1834
|
this.cleanup(runId);
|
|
@@ -1453,14 +1890,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1453
1890
|
const span = this.spans.get(runId);
|
|
1454
1891
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1455
1892
|
}
|
|
1456
|
-
|
|
1457
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1458
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1459
|
-
properties: {
|
|
1460
|
-
"error.type": errorInfo.type,
|
|
1461
|
-
"error.message": errorInfo.message
|
|
1462
|
-
}
|
|
1463
|
-
});
|
|
1893
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1464
1894
|
} catch {
|
|
1465
1895
|
} finally {
|
|
1466
1896
|
this.cleanup(runId);
|
|
@@ -1515,14 +1945,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
1515
1945
|
try {
|
|
1516
1946
|
const span = this.spans.get(runId);
|
|
1517
1947
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1518
|
-
|
|
1519
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1520
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1521
|
-
properties: {
|
|
1522
|
-
"error.type": errorInfo.type,
|
|
1523
|
-
"error.message": errorInfo.message
|
|
1524
|
-
}
|
|
1525
|
-
});
|
|
1948
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1526
1949
|
} catch {
|
|
1527
1950
|
} finally {
|
|
1528
1951
|
this.cleanup(runId);
|
|
@@ -1687,18 +2110,6 @@ function asNumber(val) {
|
|
|
1687
2110
|
const n = typeof val === "number" ? val : Number(val);
|
|
1688
2111
|
return Number.isFinite(n) ? n : void 0;
|
|
1689
2112
|
}
|
|
1690
|
-
function extractErrorInfo(err) {
|
|
1691
|
-
if (err instanceof Error) {
|
|
1692
|
-
return { type: err.name || err.constructor.name, message: err.message };
|
|
1693
|
-
}
|
|
1694
|
-
if (typeof err === "object" && err !== null) {
|
|
1695
|
-
const e = err;
|
|
1696
|
-
const type = e.name ?? e.constructor?.name ?? "Error";
|
|
1697
|
-
const message = e.message ?? safeStringify(err);
|
|
1698
|
-
return { type, message };
|
|
1699
|
-
}
|
|
1700
|
-
return { type: "Error", message: String(err) };
|
|
1701
|
-
}
|
|
1702
2113
|
|
|
1703
2114
|
// src/version.ts
|
|
1704
2115
|
var libraryName = "@raindrop-ai/deep-agents";
|
|
@@ -1738,6 +2149,8 @@ function createRaindropDeepAgents(opts) {
|
|
|
1738
2149
|
traceShipper,
|
|
1739
2150
|
userId: opts.userId,
|
|
1740
2151
|
convoId: opts.convoId,
|
|
2152
|
+
eventName: opts.eventName,
|
|
2153
|
+
eventId: opts.eventId,
|
|
1741
2154
|
traceChains: opts.traceChains
|
|
1742
2155
|
});
|
|
1743
2156
|
return {
|