@raindrop-ai/deep-agents 0.1.0 → 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 +14 -7
- package/dist/index.d.ts +14 -7
- package/dist/index.js +512 -120
- package/dist/index.mjs +512 -120
- 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,19 +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, _e, _f;
|
|
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
|
+
}
|
|
426
586
|
if (target.featureFlags || source.featureFlags) {
|
|
427
|
-
out.featureFlags = { ...(
|
|
587
|
+
out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
|
|
428
588
|
}
|
|
429
589
|
if (target.attachments || source.attachments) {
|
|
430
|
-
out.attachments = [...(
|
|
590
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
431
591
|
}
|
|
432
592
|
return out;
|
|
433
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
|
+
}
|
|
434
615
|
var EventShipper = class {
|
|
435
616
|
constructor(opts) {
|
|
436
617
|
this.buffers = /* @__PURE__ */ new Map();
|
|
@@ -516,6 +697,15 @@ var EventShipper = class {
|
|
|
516
697
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
517
698
|
if (!this.enabled) return;
|
|
518
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
|
+
}
|
|
519
709
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
520
710
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
521
711
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -574,6 +764,9 @@ var EventShipper = class {
|
|
|
574
764
|
try {
|
|
575
765
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
576
766
|
this.timers.clear();
|
|
767
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
768
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
769
|
+
}
|
|
577
770
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
578
771
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
579
772
|
} finally {
|
|
@@ -583,6 +776,8 @@ var EventShipper = class {
|
|
|
583
776
|
async trackSignal(signal) {
|
|
584
777
|
var _a, _b;
|
|
585
778
|
if (!this.enabled) return;
|
|
779
|
+
const destination = currentReplayTraceDestination();
|
|
780
|
+
if (destination && destination.kind !== "workshop") return;
|
|
586
781
|
const body = [
|
|
587
782
|
{
|
|
588
783
|
event_id: signal.eventId,
|
|
@@ -617,6 +812,8 @@ var EventShipper = class {
|
|
|
617
812
|
}
|
|
618
813
|
async identify(users) {
|
|
619
814
|
if (!this.enabled) return;
|
|
815
|
+
const destination = currentReplayTraceDestination();
|
|
816
|
+
if (destination && destination.kind !== "workshop") return;
|
|
620
817
|
const list = Array.isArray(users) ? users : [users];
|
|
621
818
|
const body = list.filter((user) => {
|
|
622
819
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -669,8 +866,9 @@ var EventShipper = class {
|
|
|
669
866
|
this.buffers.delete(eventId);
|
|
670
867
|
if (!accumulated) return;
|
|
671
868
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
672
|
-
const
|
|
673
|
-
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;
|
|
674
872
|
if (!userId) {
|
|
675
873
|
if (this.debug) {
|
|
676
874
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -678,9 +876,13 @@ var EventShipper = class {
|
|
|
678
876
|
this.sticky.delete(eventId);
|
|
679
877
|
return;
|
|
680
878
|
}
|
|
681
|
-
const { wizardSession, ...restProperties } = (
|
|
682
|
-
|
|
683
|
-
|
|
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;
|
|
684
886
|
const payload = {
|
|
685
887
|
event_id: eventId,
|
|
686
888
|
user_id: userId,
|
|
@@ -688,12 +890,13 @@ var EventShipper = class {
|
|
|
688
890
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
689
891
|
ai_data: {
|
|
690
892
|
input: accumulated.input,
|
|
691
|
-
output: accumulated.output,
|
|
893
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
692
894
|
model: accumulated.model,
|
|
693
895
|
convo_id: convoId
|
|
694
896
|
},
|
|
695
897
|
properties: {
|
|
696
898
|
...restProperties,
|
|
899
|
+
...telemetryProperties,
|
|
697
900
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
698
901
|
$context: this.context
|
|
699
902
|
},
|
|
@@ -721,29 +924,30 @@ var EventShipper = class {
|
|
|
721
924
|
endpoint: url
|
|
722
925
|
});
|
|
723
926
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
});
|
|
731
|
-
}
|
|
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;
|
|
732
933
|
if (!this.writeKey) {
|
|
733
934
|
if (!isPending) this.sticky.delete(eventId);
|
|
935
|
+
if (mirror) await mirror;
|
|
734
936
|
return;
|
|
735
937
|
}
|
|
736
938
|
const opts = this.requestOpts();
|
|
737
939
|
if (!opts) {
|
|
738
940
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
739
941
|
if (!isPending) this.sticky.delete(eventId);
|
|
942
|
+
if (mirror) await mirror;
|
|
740
943
|
return;
|
|
741
944
|
}
|
|
742
945
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
743
|
-
|
|
946
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
947
|
+
this.inFlight.add(combined);
|
|
744
948
|
try {
|
|
745
949
|
try {
|
|
746
|
-
await
|
|
950
|
+
await combined;
|
|
747
951
|
if (this.debug) {
|
|
748
952
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
749
953
|
}
|
|
@@ -755,13 +959,156 @@ var EventShipper = class {
|
|
|
755
959
|
);
|
|
756
960
|
}
|
|
757
961
|
} finally {
|
|
758
|
-
this.inFlight.delete(
|
|
962
|
+
this.inFlight.delete(combined);
|
|
759
963
|
}
|
|
760
964
|
if (!isPending) {
|
|
761
965
|
this.sticky.delete(eventId);
|
|
762
966
|
}
|
|
763
967
|
}
|
|
764
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
|
+
}
|
|
765
1112
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
766
1113
|
"apikey",
|
|
767
1114
|
"apisecret",
|
|
@@ -851,6 +1198,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
851
1198
|
if (scrubbedJson === json) return void 0;
|
|
852
1199
|
return { stringValue: scrubbedJson };
|
|
853
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
|
+
}
|
|
854
1208
|
function applyOtelSpanAttributeLimit(limit) {
|
|
855
1209
|
var _a, _b;
|
|
856
1210
|
try {
|
|
@@ -946,7 +1300,10 @@ var TraceShipper = class {
|
|
|
946
1300
|
try {
|
|
947
1301
|
const result = this.transformSpanHook(current);
|
|
948
1302
|
if (result === null) return null;
|
|
949
|
-
if (result !== void 0)
|
|
1303
|
+
if (result !== void 0) {
|
|
1304
|
+
copyReplayTraceDestination(current, result);
|
|
1305
|
+
current = result;
|
|
1306
|
+
}
|
|
950
1307
|
} catch (err) {
|
|
951
1308
|
if (this.debug) {
|
|
952
1309
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -955,10 +1312,20 @@ var TraceShipper = class {
|
|
|
955
1312
|
return null;
|
|
956
1313
|
}
|
|
957
1314
|
}
|
|
1315
|
+
try {
|
|
1316
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1317
|
+
copyReplayTraceDestination(current, normalized);
|
|
1318
|
+
current = normalized;
|
|
1319
|
+
} catch (e) {
|
|
1320
|
+
}
|
|
958
1321
|
if (!this.disableDefaultRedaction) {
|
|
959
|
-
|
|
1322
|
+
const redacted = defaultTransformSpan(current);
|
|
1323
|
+
copyReplayTraceDestination(current, redacted);
|
|
1324
|
+
current = redacted;
|
|
960
1325
|
}
|
|
961
|
-
|
|
1326
|
+
const capped = this.capSpanAttributes(current);
|
|
1327
|
+
copyReplayTraceDestination(current, capped);
|
|
1328
|
+
return capped;
|
|
962
1329
|
}
|
|
963
1330
|
isDebugEnabled() {
|
|
964
1331
|
return this.debug;
|
|
@@ -975,33 +1342,55 @@ var TraceShipper = class {
|
|
|
975
1342
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
976
1343
|
const attrs = [
|
|
977
1344
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
978
|
-
|
|
1345
|
+
...identityAttrs(args),
|
|
1346
|
+
attrString("ai.operationId", args.operationId),
|
|
1347
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
979
1348
|
];
|
|
980
1349
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
981
|
-
const span = {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
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);
|
|
993
1368
|
return span;
|
|
994
1369
|
}
|
|
995
|
-
mirrorToLocalDebugger(span) {
|
|
996
|
-
|
|
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;
|
|
997
1375
|
const redacted = this.redactSpan(span);
|
|
998
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
|
+
}
|
|
999
1384
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1000
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1001
|
-
baseUrl:
|
|
1385
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1386
|
+
baseUrl: localDebuggerUrl,
|
|
1002
1387
|
debug: false,
|
|
1003
1388
|
sdkName: this.sdkName
|
|
1004
1389
|
});
|
|
1390
|
+
this.inFlight.add(p);
|
|
1391
|
+
void p.finally(() => {
|
|
1392
|
+
this.inFlight.delete(p);
|
|
1393
|
+
});
|
|
1005
1394
|
}
|
|
1006
1395
|
endSpan(span, extra) {
|
|
1007
1396
|
var _a, _b;
|
|
@@ -1023,14 +1412,17 @@ var TraceShipper = class {
|
|
|
1023
1412
|
attributes: span.attributes,
|
|
1024
1413
|
status
|
|
1025
1414
|
});
|
|
1415
|
+
copyReplayTraceDestination(span, otlp);
|
|
1026
1416
|
this.enqueue(otlp);
|
|
1027
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1417
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1028
1418
|
}
|
|
1029
1419
|
createSpan(args) {
|
|
1030
1420
|
var _a;
|
|
1031
1421
|
const ids = createSpanIds(args.parent);
|
|
1032
1422
|
const attrs = [
|
|
1033
|
-
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))
|
|
1034
1426
|
];
|
|
1035
1427
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1036
1428
|
const otlp = buildOtlpSpan({
|
|
@@ -1041,8 +1433,9 @@ var TraceShipper = class {
|
|
|
1041
1433
|
attributes: attrs,
|
|
1042
1434
|
status: args.status
|
|
1043
1435
|
});
|
|
1436
|
+
rememberReplayTraceDestination(otlp);
|
|
1044
1437
|
this.enqueue(otlp);
|
|
1045
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1438
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1046
1439
|
}
|
|
1047
1440
|
enqueue(span) {
|
|
1048
1441
|
if (!this.enabled) return;
|
|
@@ -1056,6 +1449,13 @@ var TraceShipper = class {
|
|
|
1056
1449
|
}
|
|
1057
1450
|
const redacted = this.redactSpan(span);
|
|
1058
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;
|
|
1059
1459
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1060
1460
|
this.queue.shift();
|
|
1061
1461
|
}
|
|
@@ -1074,47 +1474,67 @@ var TraceShipper = class {
|
|
|
1074
1474
|
}
|
|
1075
1475
|
}
|
|
1076
1476
|
async flush() {
|
|
1077
|
-
|
|
1477
|
+
var _a;
|
|
1478
|
+
if (!this.enabled) {
|
|
1479
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1480
|
+
})));
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1078
1483
|
if (this.timer) {
|
|
1079
1484
|
clearTimeout(this.timer);
|
|
1080
1485
|
this.timer = void 0;
|
|
1081
1486
|
}
|
|
1082
1487
|
while (this.queue.length > 0) {
|
|
1083
1488
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1084
|
-
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1091
|
-
)
|
|
1092
|
-
);
|
|
1093
|
-
continue;
|
|
1094
|
-
}
|
|
1095
|
-
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
1096
|
-
const url = `${this.baseUrl}traces`;
|
|
1097
|
-
if (this.debug) {
|
|
1098
|
-
console.log(`${this.prefix} sending traces batch`, {
|
|
1099
|
-
spans: batch.length,
|
|
1100
|
-
endpoint: url
|
|
1101
|
-
});
|
|
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]);
|
|
1102
1495
|
}
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1109
|
-
} catch (err) {
|
|
1110
|
-
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) {
|
|
1111
1501
|
rateLimitedLog(
|
|
1112
|
-
`${this.prefix}.
|
|
1113
|
-
() => console.warn(
|
|
1502
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1503
|
+
() => console.warn(
|
|
1504
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1505
|
+
)
|
|
1114
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);
|
|
1115
1537
|
}
|
|
1116
|
-
} finally {
|
|
1117
|
-
this.inFlight.delete(p);
|
|
1118
1538
|
}
|
|
1119
1539
|
}
|
|
1120
1540
|
}
|
|
@@ -1157,7 +1577,9 @@ var TraceShipper = class {
|
|
|
1157
1577
|
if (!settled) {
|
|
1158
1578
|
rateLimitedLog(
|
|
1159
1579
|
`${this.prefix}.shutdown_deadline`,
|
|
1160
|
-
() => console.warn(
|
|
1580
|
+
() => console.warn(
|
|
1581
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
1582
|
+
)
|
|
1161
1583
|
);
|
|
1162
1584
|
}
|
|
1163
1585
|
} finally {
|
|
@@ -1309,6 +1731,10 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1309
1731
|
});
|
|
1310
1732
|
}
|
|
1311
1733
|
}
|
|
1734
|
+
rootErrorPatch(runId, error) {
|
|
1735
|
+
const rootId = this.rootRunIds.get(runId) ?? runId;
|
|
1736
|
+
return rootId === runId ? { error } : void 0;
|
|
1737
|
+
}
|
|
1312
1738
|
// ---------------------------------------------------------------------------
|
|
1313
1739
|
// LLM events
|
|
1314
1740
|
// ---------------------------------------------------------------------------
|
|
@@ -1404,8 +1830,6 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1404
1830
|
]
|
|
1405
1831
|
});
|
|
1406
1832
|
const properties = {};
|
|
1407
|
-
if (promptTokens != null) properties["ai.usage.prompt_tokens"] = promptTokens;
|
|
1408
|
-
if (completionTokens != null) properties["ai.usage.completion_tokens"] = completionTokens;
|
|
1409
1833
|
if (cachedTokens != null) properties["ai.usage.cached_tokens"] = cachedTokens;
|
|
1410
1834
|
if (reasoningTokens != null) properties["ai.usage.thoughts_tokens"] = reasoningTokens;
|
|
1411
1835
|
if (finishReason != null) properties["ai.finish_reason"] = finishReason;
|
|
@@ -1413,6 +1837,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1413
1837
|
await this.finalizeEventIfRoot(runId, {
|
|
1414
1838
|
output: cappedOutput,
|
|
1415
1839
|
model,
|
|
1840
|
+
usage: { promptTokens, completionTokens },
|
|
1416
1841
|
properties: Object.keys(properties).length > 0 ? properties : void 0
|
|
1417
1842
|
});
|
|
1418
1843
|
} catch {
|
|
@@ -1430,14 +1855,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1430
1855
|
if (span) {
|
|
1431
1856
|
this.traceShipper.endSpan(span, { error: err });
|
|
1432
1857
|
}
|
|
1433
|
-
|
|
1434
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1435
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1436
|
-
properties: {
|
|
1437
|
-
"error.type": errorInfo.type,
|
|
1438
|
-
"error.message": errorInfo.message
|
|
1439
|
-
}
|
|
1440
|
-
});
|
|
1858
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1441
1859
|
} catch {
|
|
1442
1860
|
} finally {
|
|
1443
1861
|
this.cleanup(runId);
|
|
@@ -1499,14 +1917,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1499
1917
|
const span = this.spans.get(runId);
|
|
1500
1918
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1501
1919
|
}
|
|
1502
|
-
|
|
1503
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1504
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1505
|
-
properties: {
|
|
1506
|
-
"error.type": errorInfo.type,
|
|
1507
|
-
"error.message": errorInfo.message
|
|
1508
|
-
}
|
|
1509
|
-
});
|
|
1920
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1510
1921
|
} catch {
|
|
1511
1922
|
} finally {
|
|
1512
1923
|
this.cleanup(runId);
|
|
@@ -1561,14 +1972,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
|
|
|
1561
1972
|
try {
|
|
1562
1973
|
const span = this.spans.get(runId);
|
|
1563
1974
|
if (span) this.traceShipper.endSpan(span, { error: err });
|
|
1564
|
-
|
|
1565
|
-
await this.finalizeEventIfRoot(runId, {
|
|
1566
|
-
output: `[Error] ${errorInfo.type}: ${errorInfo.message}`,
|
|
1567
|
-
properties: {
|
|
1568
|
-
"error.type": errorInfo.type,
|
|
1569
|
-
"error.message": errorInfo.message
|
|
1570
|
-
}
|
|
1571
|
-
});
|
|
1975
|
+
await this.finalizeEventIfRoot(runId, this.rootErrorPatch(runId, err));
|
|
1572
1976
|
} catch {
|
|
1573
1977
|
} finally {
|
|
1574
1978
|
this.cleanup(runId);
|
|
@@ -1733,18 +2137,6 @@ function asNumber(val) {
|
|
|
1733
2137
|
const n = typeof val === "number" ? val : Number(val);
|
|
1734
2138
|
return Number.isFinite(n) ? n : void 0;
|
|
1735
2139
|
}
|
|
1736
|
-
function extractErrorInfo(err) {
|
|
1737
|
-
if (err instanceof Error) {
|
|
1738
|
-
return { type: err.name || err.constructor.name, message: err.message };
|
|
1739
|
-
}
|
|
1740
|
-
if (typeof err === "object" && err !== null) {
|
|
1741
|
-
const e = err;
|
|
1742
|
-
const type = e.name ?? e.constructor?.name ?? "Error";
|
|
1743
|
-
const message = e.message ?? safeStringify(err);
|
|
1744
|
-
return { type, message };
|
|
1745
|
-
}
|
|
1746
|
-
return { type: "Error", message: String(err) };
|
|
1747
|
-
}
|
|
1748
2140
|
|
|
1749
2141
|
// src/version.ts
|
|
1750
2142
|
var libraryName = "@raindrop-ai/deep-agents";
|