@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/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-WKRW55KX.js
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
- void postJson(`${baseUrl}traces`, body, {}, {
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
- void postJson(`${baseUrl}events/track_partial`, event, headers, {
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 = [...(_c = target.attachments) != null ? _c : [], ...(_d = source.attachments) != null ? _d : []];
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 eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
643
- const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
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 } = (_e = accumulated.properties) != null ? _e : {};
652
- const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
653
- const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
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
- if (this.localDebuggerUrl) {
694
- mirrorPartialEventToLocalDebugger(payload, {
695
- baseUrl: this.localDebuggerUrl,
696
- writeKey: this.writeKey,
697
- debug: this.debug,
698
- sdkName: this.sdkName
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
- this.inFlight.add(p);
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 p;
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(p);
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) current = result;
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
- current = defaultTransformSpan(current);
1295
+ const redacted = defaultTransformSpan(current);
1296
+ copyReplayTraceDestination(current, redacted);
1297
+ current = redacted;
929
1298
  }
930
- return this.capSpanAttributes(current);
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
- attrString("ai.operationId", args.operationId)
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 = { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
951
- this.mirrorToLocalDebugger(
952
- buildOtlpSpan({
953
- ids: span.ids,
954
- name: span.name,
955
- startTimeUnixNano: span.startTimeUnixNano,
956
- endTimeUnixNano: span.startTimeUnixNano,
957
- // placeholder — will be updated on endSpan
958
- attributes: span.attributes,
959
- status: { code: SpanStatusCode.UNSET }
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
- if (!this.localDebuggerUrl) return;
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: this.localDebuggerUrl,
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
- if (!this.enabled) return;
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
- if (!this.writeKey) continue;
1054
- const opts = this.requestOpts();
1055
- if (!opts) {
1056
- rateLimitedLog(
1057
- `${this.prefix}.shutdown_deadline`,
1058
- () => console.warn(
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 p = postJson(url, body, this.requestHeaders(), opts);
1073
- this.inFlight.add(p);
1074
- try {
1075
- try {
1076
- await p;
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}.send_spans_failed`,
1082
- () => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
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(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
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, randomUUID());
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
- const errorInfo = extractErrorInfo(err);
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
- const errorInfo = extractErrorInfo(err);
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
- const errorInfo = extractErrorInfo(err);
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 {