@raindrop-ai/ai-sdk 0.0.40 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,14 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
 
3
- // ../core/dist/chunk-SK6EJEO7.js
3
+ // ../core/dist/chunk-Y5LUB7OE.js
4
+ function normalizeFeatureFlags(input) {
5
+ if (Array.isArray(input)) {
6
+ return Object.fromEntries(input.map((name) => [name, "true"]));
7
+ }
8
+ return Object.fromEntries(
9
+ Object.entries(input).map(([k, v]) => [k, String(v)])
10
+ );
11
+ }
4
12
  function getCrypto() {
5
13
  const c = globalThis.crypto;
6
14
  return c;
@@ -55,6 +63,20 @@ function base64Encode(bytes) {
55
63
  }
56
64
  return out;
57
65
  }
66
+ function runWithTracingSuppressed(fn) {
67
+ const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
68
+ if (typeof hook !== "function") return fn();
69
+ let started = false;
70
+ try {
71
+ return hook(() => {
72
+ started = true;
73
+ return fn();
74
+ });
75
+ } catch (err) {
76
+ if (started) throw err;
77
+ return fn();
78
+ }
79
+ }
58
80
  var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
59
81
  var MAX_RETRY_DELAY_MS = 3e4;
60
82
  function wait(ms) {
@@ -165,15 +187,17 @@ async function postJson(url, body, headers, opts) {
165
187
  const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
166
188
  await withRetry(
167
189
  async () => {
168
- const resp = await fetch(url, {
169
- method: "POST",
170
- headers: {
171
- "Content-Type": "application/json",
172
- ...headers
173
- },
174
- body: JSON.stringify(body),
175
- signal: AbortSignal.timeout(timeoutMs)
176
- });
190
+ const resp = await runWithTracingSuppressed(
191
+ () => fetch(url, {
192
+ method: "POST",
193
+ headers: {
194
+ "Content-Type": "application/json",
195
+ ...headers
196
+ },
197
+ body: JSON.stringify(body),
198
+ signal: AbortSignal.timeout(timeoutMs)
199
+ })
200
+ );
177
201
  if (!resp.ok) {
178
202
  const text = await resp.text().catch(() => "");
179
203
  const err = new Error(
@@ -419,13 +443,16 @@ function projectIdHeaders(projectId) {
419
443
  var SHUTDOWN_DEADLINE_MS = 1e4;
420
444
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
421
445
  function mergePatches(target, source) {
422
- var _a, _b, _c, _d;
446
+ var _a, _b, _c, _d, _e, _f;
423
447
  const out = { ...target, ...source };
424
448
  if (target.properties || source.properties) {
425
449
  out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
426
450
  }
451
+ if (target.featureFlags || source.featureFlags) {
452
+ out.featureFlags = { ...(_c = target.featureFlags) != null ? _c : {}, ...(_d = source.featureFlags) != null ? _d : {} };
453
+ }
427
454
  if (target.attachments || source.attachments) {
428
- out.attachments = [...(_c = target.attachments) != null ? _c : [], ...(_d = source.attachments) != null ? _d : []];
455
+ out.attachments = [...(_e = target.attachments) != null ? _e : [], ...(_f = source.attachments) != null ? _f : []];
429
456
  }
430
457
  return out;
431
458
  }
@@ -695,6 +722,7 @@ var EventShipper = class {
695
722
  ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
696
723
  $context: this.context
697
724
  },
725
+ ...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
698
726
  attachments: accumulated.attachments,
699
727
  is_pending: isPending
700
728
  };
@@ -1280,6 +1308,31 @@ async function* asyncGeneratorWithCurrent(span, gen) {
1280
1308
  }
1281
1309
  }
1282
1310
  globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
1311
+ var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
1312
+ "OpenTelemetry SDK Context Key SUPPRESS_TRACING"
1313
+ );
1314
+ function findOtelContextManager() {
1315
+ var _a;
1316
+ for (const sym of Object.getOwnPropertySymbols(globalThis)) {
1317
+ if (!((_a = sym.description) == null ? void 0 : _a.startsWith("opentelemetry.js.api."))) continue;
1318
+ const api = globalThis[sym];
1319
+ const cm = api == null ? void 0 : api.context;
1320
+ if (cm && typeof cm.with === "function" && typeof cm.active === "function") {
1321
+ return cm;
1322
+ }
1323
+ }
1324
+ return void 0;
1325
+ }
1326
+ function installTracingSuppressionHook() {
1327
+ if (typeof globalThis.RAINDROP_SUPPRESS_TRACING === "function") return;
1328
+ const hook = (fn) => {
1329
+ const cm = findOtelContextManager();
1330
+ if (!cm) return fn();
1331
+ return cm.with(cm.active().setValue(SUPPRESS_TRACING_KEY, true), fn);
1332
+ };
1333
+ globalThis.RAINDROP_SUPPRESS_TRACING = hook;
1334
+ }
1335
+ installTracingSuppressionHook();
1283
1336
 
1284
1337
  // src/internal/truncation.ts
1285
1338
  var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
@@ -2684,6 +2737,20 @@ var RaindropTelemetryIntegration = class {
2684
2737
  } else if (properties && typeof properties === "object") {
2685
2738
  result.properties = properties;
2686
2739
  }
2740
+ const featureFlags = metadata["raindrop.featureFlags"];
2741
+ if (typeof featureFlags === "string") {
2742
+ try {
2743
+ const parsed = JSON.parse(featureFlags);
2744
+ if (parsed && typeof parsed === "object") {
2745
+ result.featureFlags = normalizeFeatureFlags(parsed);
2746
+ }
2747
+ } catch (e) {
2748
+ }
2749
+ } else if (featureFlags && typeof featureFlags === "object") {
2750
+ result.featureFlags = normalizeFeatureFlags(
2751
+ featureFlags
2752
+ );
2753
+ }
2687
2754
  return result;
2688
2755
  }
2689
2756
  /**
@@ -2898,7 +2965,7 @@ var RaindropTelemetryIntegration = class {
2898
2965
  * same event ID into a separate canonical row.
2899
2966
  */
2900
2967
  finalizeGenerateEvent(state, output, model, keepPending = false) {
2901
- var _a, _b, _c, _d, _e, _f, _g, _h;
2968
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2902
2969
  const suppressSubagentEvent = state.subagentName !== void 0 && state.subagentToolCallSpan !== void 0;
2903
2970
  if (!this.sendEvents || suppressSubagentEvent) return;
2904
2971
  const callMeta = this.extractRaindropMetadata(state.metadata);
@@ -2911,7 +2978,11 @@ var RaindropTelemetryIntegration = class {
2911
2978
  ...(_f = this.defaultContext) == null ? void 0 : _f.properties,
2912
2979
  ...callMeta.properties
2913
2980
  };
2914
- const convoId = (_h = callMeta.convoId) != null ? _h : (_g = this.defaultContext) == null ? void 0 : _g.convoId;
2981
+ const featureFlags = {
2982
+ ...(_g = this.defaultContext) == null ? void 0 : _g.featureFlags,
2983
+ ...callMeta.featureFlags
2984
+ };
2985
+ const convoId = (_i = callMeta.convoId) != null ? _i : (_h = this.defaultContext) == null ? void 0 : _h.convoId;
2915
2986
  void this.eventShipper.patch(state.eventId, {
2916
2987
  eventName,
2917
2988
  userId,
@@ -2920,6 +2991,7 @@ var RaindropTelemetryIntegration = class {
2920
2991
  output: cappedOutput,
2921
2992
  model,
2922
2993
  properties: Object.keys(properties).length > 0 ? properties : void 0,
2994
+ featureFlags: Object.keys(featureFlags).length > 0 ? featureFlags : void 0,
2923
2995
  isPending: keepPending
2924
2996
  }).catch((err) => {
2925
2997
  if (this.debug) {
@@ -3230,6 +3302,20 @@ function extractRaindropMetadata(metadata) {
3230
3302
  } else if (properties && typeof properties === "object") {
3231
3303
  result.properties = properties;
3232
3304
  }
3305
+ const featureFlags = metadata["raindrop.featureFlags"];
3306
+ if (typeof featureFlags === "string") {
3307
+ try {
3308
+ const parsed = JSON.parse(featureFlags);
3309
+ if (parsed && typeof parsed === "object") {
3310
+ result.featureFlags = normalizeFeatureFlags(parsed);
3311
+ }
3312
+ } catch (e) {
3313
+ }
3314
+ } else if (featureFlags && typeof featureFlags === "object") {
3315
+ result.featureFlags = normalizeFeatureFlags(
3316
+ featureFlags
3317
+ );
3318
+ }
3233
3319
  return result;
3234
3320
  }
3235
3321
  function mergeContexts(wrapTime, callTime) {
@@ -3244,6 +3330,10 @@ function mergeContexts(wrapTime, callTime) {
3244
3330
  ...callTime.properties
3245
3331
  };
3246
3332
  }
3333
+ if (callTime.featureFlags) {
3334
+ const wrapTimeFlags = wrapTime.featureFlags ? normalizeFeatureFlags(wrapTime.featureFlags) : {};
3335
+ result.featureFlags = { ...wrapTimeFlags, ...callTime.featureFlags };
3336
+ }
3247
3337
  return result;
3248
3338
  }
3249
3339
  function detectAISDKVersion(aiSDK) {
@@ -3556,6 +3646,7 @@ function createFinalize(params) {
3556
3646
  output: defaultOutput,
3557
3647
  model,
3558
3648
  properties: setup.ctx.properties,
3649
+ featureFlags: setup.ctx.featureFlags ? normalizeFeatureFlags(setup.ctx.featureFlags) : void 0,
3559
3650
  attachments: mergeAttachments(setup.ctx.attachments, inputAttachments, outputAttachments)
3560
3651
  };
3561
3652
  const built = await maybeBuildEvent(options.buildEvent, allMessages);
@@ -3609,6 +3700,7 @@ function createFinalize(params) {
3609
3700
  output,
3610
3701
  model: finalModel,
3611
3702
  properties: patch.properties,
3703
+ featureFlags: patch.featureFlags,
3612
3704
  attachments: patch.attachments,
3613
3705
  isPending: keepEventPending
3614
3706
  }).catch((err) => {
@@ -3840,7 +3932,8 @@ function wrapAISDK(aiSDK, deps) {
3840
3932
  eventId: wrapTimeCtx.eventId,
3841
3933
  eventName: wrapTimeCtx.eventName,
3842
3934
  convoId: wrapTimeCtx.convoId,
3843
- properties: wrapTimeCtx.properties
3935
+ properties: wrapTimeCtx.properties,
3936
+ featureFlags: wrapTimeCtx.featureFlags ? normalizeFeatureFlags(wrapTimeCtx.featureFlags) : void 0
3844
3937
  }
3845
3938
  });
3846
3939
  const registerFn = resolveRegisterTelemetry(aiSDK);
@@ -4116,6 +4209,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
4116
4209
  output: outputText,
4117
4210
  model,
4118
4211
  properties: ctx.properties,
4212
+ featureFlags: ctx.featureFlags ? normalizeFeatureFlags(ctx.featureFlags) : void 0,
4119
4213
  attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
4120
4214
  };
4121
4215
  const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
@@ -4183,6 +4277,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
4183
4277
  output,
4184
4278
  model: finalModel,
4185
4279
  properties: patch.properties,
4280
+ featureFlags: patch.featureFlags,
4186
4281
  attachments: patch.attachments,
4187
4282
  isPending: false
4188
4283
  }).catch((err) => {
@@ -4324,6 +4419,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
4324
4419
  output: outputText,
4325
4420
  model,
4326
4421
  properties: ctx.properties,
4422
+ featureFlags: ctx.featureFlags ? normalizeFeatureFlags(ctx.featureFlags) : void 0,
4327
4423
  attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
4328
4424
  };
4329
4425
  const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
@@ -4391,6 +4487,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
4391
4487
  output,
4392
4488
  model: finalModel,
4393
4489
  properties: patch.properties,
4490
+ featureFlags: patch.featureFlags,
4394
4491
  attachments: patch.attachments,
4395
4492
  isPending: false
4396
4493
  }).catch((err) => {
@@ -4988,7 +5085,7 @@ async function maybeBuildEvent(buildEvent, messages) {
4988
5085
  }
4989
5086
  }
4990
5087
  function mergeBuildEventPatch(defaults, override) {
4991
- var _a, _b, _c, _d, _e, _f, _g, _h;
5088
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4992
5089
  if (!override) return defaults;
4993
5090
  return {
4994
5091
  eventName: (_a = override.eventName) != null ? _a : defaults.eventName,
@@ -4996,7 +5093,8 @@ function mergeBuildEventPatch(defaults, override) {
4996
5093
  output: (_c = override.output) != null ? _c : defaults.output,
4997
5094
  model: (_d = override.model) != null ? _d : defaults.model,
4998
5095
  properties: override.properties !== void 0 ? { ...(_e = defaults.properties) != null ? _e : {}, ...(_f = override.properties) != null ? _f : {} } : defaults.properties,
4999
- attachments: override.attachments !== void 0 ? [...(_g = defaults.attachments) != null ? _g : [], ...(_h = override.attachments) != null ? _h : []] : defaults.attachments
5096
+ featureFlags: override.featureFlags !== void 0 ? { ...(_g = defaults.featureFlags) != null ? _g : {}, ...(_h = override.featureFlags) != null ? _h : {} } : defaults.featureFlags,
5097
+ attachments: override.attachments !== void 0 ? [...(_i = defaults.attachments) != null ? _i : [], ...(_j = override.attachments) != null ? _j : []] : defaults.attachments
5000
5098
  };
5001
5099
  }
5002
5100
  function mergeAttachments(...groups) {
@@ -5017,7 +5115,7 @@ function extractNestedTokens(usage, key) {
5017
5115
  // package.json
5018
5116
  var package_default = {
5019
5117
  name: "@raindrop-ai/ai-sdk",
5020
- version: "0.0.40"};
5118
+ version: "0.1.0"};
5021
5119
 
5022
5120
  // src/internal/version.ts
5023
5121
  var libraryName = package_default.name;
@@ -5062,6 +5160,8 @@ function eventMetadata(options) {
5062
5160
  if (options.convoId) result["raindrop.convoId"] = options.convoId;
5063
5161
  if (options.eventName) result["raindrop.eventName"] = options.eventName;
5064
5162
  if (options.properties) result["raindrop.properties"] = JSON.stringify(options.properties);
5163
+ if (options.featureFlags)
5164
+ result["raindrop.featureFlags"] = JSON.stringify(normalizeFeatureFlags(options.featureFlags));
5065
5165
  return result;
5066
5166
  }
5067
5167
  function deriveChatTurnMessageId(request) {
@@ -5166,7 +5266,8 @@ function createRaindropAISDK(opts) {
5166
5266
  "eventId",
5167
5267
  "eventName",
5168
5268
  "convoId",
5169
- "properties"
5269
+ "properties",
5270
+ "featureFlags"
5170
5271
  ];
5171
5272
  let context;
5172
5273
  let subagentWrapping;
@@ -5198,6 +5299,9 @@ function createRaindropAISDK(opts) {
5198
5299
  async setProperties(eventId, properties) {
5199
5300
  await eventShipper.patch(eventId, { properties });
5200
5301
  },
5302
+ async setFeatureFlags(eventId, featureFlags) {
5303
+ await eventShipper.patch(eventId, { featureFlags: normalizeFeatureFlags(featureFlags) });
5304
+ },
5201
5305
  async finish(eventId, patch) {
5202
5306
  await eventShipper.finish(eventId, patch);
5203
5307
  }
@@ -5298,4 +5402,4 @@ function raindrop(options = {}) {
5298
5402
  return client.createTelemetryIntegration({ context, subagentWrapping });
5299
5403
  }
5300
5404
 
5301
- export { DEFAULT_MAX_TEXT_FIELD_CHARS2 as DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER2 as TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText2 as capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent };
5405
+ export { DEFAULT_MAX_TEXT_FIELD_CHARS2 as DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER2 as TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText2 as capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, normalizeFeatureFlags, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent };
@@ -1,3 +1,14 @@
1
+ type FeatureFlagValue = string | number | boolean;
2
+ type FeatureFlags = string[] | Record<string, FeatureFlagValue>;
3
+ /**
4
+ * Normalizes feature flags from the two accepted input forms into a
5
+ * canonical `Record<string, string>` ready for the wire payload.
6
+ *
7
+ * - Array form: `["a", "b"]` → `{"a": "true", "b": "true"}`
8
+ * - Object form: `{ a: "v2", b: true, c: 3 }` → `{"a": "v2", "b": "true", "c": "3"}`
9
+ */
10
+ declare function normalizeFeatureFlags(input: FeatureFlags): Record<string, string>;
11
+
1
12
  type OtlpAnyValue = {
2
13
  stringValue?: string;
3
14
  intValue?: string;
@@ -53,6 +64,7 @@ type Patch = {
53
64
  output?: string;
54
65
  model?: string;
55
66
  properties?: Record<string, unknown>;
67
+ featureFlags?: Record<string, string>;
56
68
  attachments?: Attachment$1[];
57
69
  isPending?: boolean;
58
70
  timestamp?: string;
@@ -153,6 +165,7 @@ declare class EventShipper$1 {
153
165
  output?: string;
154
166
  model?: string;
155
167
  properties?: Record<string, unknown>;
168
+ featureFlags?: Record<string, string>;
156
169
  userId?: string;
157
170
  }): Promise<void>;
158
171
  flush(): Promise<void>;
@@ -416,6 +429,42 @@ declare class TraceShipper$1 {
416
429
  shutdown(): Promise<void>;
417
430
  }
418
431
 
432
+ /**
433
+ * Run telemetry egress with OpenTelemetry tracing suppressed.
434
+ *
435
+ * Why this exists
436
+ * ---------------
437
+ * Raindrop integrations ship spans/events over HTTP with the global `fetch`
438
+ * (see {@link ../http.ts `postJson`}). When the host app also runs an OTel
439
+ * fetch/undici instrumentation — e.g. `@vercel/otel`'s `registerOTel`, which
440
+ * every Eve agent installs — that instrumentation wraps *our own* telemetry
441
+ * POSTs in a `fetch POST <endpoint>` span. Those spans are then handed to the
442
+ * very exporter that issued the request, so they get shipped right back to
443
+ * Raindrop and Workshop as standalone "runs" (and, because each export issues
444
+ * another fetch, they feed back on themselves). The result is a run list
445
+ * flooded with `fetch POST .../v1/traces`, `.../events/track_partial` and
446
+ * `.../live` entries that drown out the real agent turns — especially with
447
+ * sub-agents, where every sandbox runs its own instrumentation.
448
+ *
449
+ * The OTel-blessed fix is to mark the active context as "tracing suppressed"
450
+ * around the request; instrumentations check `isTracingSuppressed` and return
451
+ * a no-op span instead of recording one. We do this through a hook stashed on
452
+ * `globalThis` by the Node entrypoint ({@link ../index.node.ts}) so that:
453
+ * - `@opentelemetry/api` / `@opentelemetry/core` stay *optional* — core never
454
+ * hard-depends on them, and the hook is simply absent when they (and thus
455
+ * any instrumentation to suppress) are not installed; and
456
+ * - the browser bundle never pulls in `node:module`, mirroring how core
457
+ * injects `AsyncLocalStorage` via `RAINDROP_ASYNC_LOCAL_STORAGE`.
458
+ *
459
+ * When no hook is present the callback runs unchanged, so suppression is a
460
+ * best-effort no-op rather than a hard requirement.
461
+ */
462
+ /** Hook signature: run `fn` with OTel tracing suppressed, returning its value. */
463
+ type SuppressTracingHook = <T>(fn: () => T) => T;
464
+ declare global {
465
+ var RAINDROP_SUPPRESS_TRACING: SuppressTracingHook | undefined;
466
+ }
467
+
419
468
  type ParentSpanContext = {
420
469
  traceIdB64: string;
421
470
  spanIdB64: string;
@@ -527,6 +576,7 @@ type RaindropTelemetryIntegrationOptions = {
527
576
  eventName?: string;
528
577
  convoId?: string;
529
578
  properties?: Record<string, unknown>;
579
+ featureFlags?: Record<string, string>;
530
580
  };
531
581
  };
532
582
  declare class RaindropTelemetryIntegration implements TelemetryIntegration {
@@ -803,6 +853,8 @@ type EventMetadataOptions = {
803
853
  eventName?: string;
804
854
  /** Additional properties to merge with wrap-time properties */
805
855
  properties?: Record<string, unknown>;
856
+ /** Feature flags to attach to this event (merged with wrap-time flags; call-time wins) */
857
+ featureFlags?: FeatureFlags;
806
858
  };
807
859
  /**
808
860
  * Creates metadata for use with the AI SDK's `experimental_telemetry.metadata` option.
@@ -1006,6 +1058,7 @@ type RaindropAISDKContext = {
1006
1058
  eventName?: string;
1007
1059
  convoId?: string;
1008
1060
  properties?: Record<string, unknown>;
1061
+ featureFlags?: FeatureFlags;
1009
1062
  attachments?: Attachment[];
1010
1063
  };
1011
1064
 
@@ -1015,6 +1068,7 @@ type BuildEventPatch = {
1015
1068
  output?: string;
1016
1069
  model?: string;
1017
1070
  properties?: Record<string, unknown>;
1071
+ featureFlags?: Record<string, string>;
1018
1072
  attachments?: Attachment[];
1019
1073
  };
1020
1074
  /**
@@ -1179,6 +1233,7 @@ type EventPatch = {
1179
1233
  output?: string;
1180
1234
  model?: string;
1181
1235
  properties?: Record<string, unknown>;
1236
+ featureFlags?: Record<string, string>;
1182
1237
  attachments?: Attachment[];
1183
1238
  isPending?: boolean;
1184
1239
  timestamp?: string;
@@ -1211,10 +1266,12 @@ type RaindropAISDKClient = {
1211
1266
  patch(eventId: string, patch: EventPatch): Promise<void>;
1212
1267
  addAttachments(eventId: string, attachments: Attachment[]): Promise<void>;
1213
1268
  setProperties(eventId: string, properties: Record<string, unknown>): Promise<void>;
1269
+ setFeatureFlags(eventId: string, featureFlags: FeatureFlags): Promise<void>;
1214
1270
  finish(eventId: string, patch: {
1215
1271
  output?: string;
1216
1272
  model?: string;
1217
1273
  properties?: Record<string, unknown>;
1274
+ featureFlags?: Record<string, string>;
1218
1275
  }): Promise<void>;
1219
1276
  };
1220
1277
  /**
@@ -1325,4 +1382,4 @@ type RaindropTelemetryOptions = RaindropAISDKOptions & {
1325
1382
  */
1326
1383
  declare function raindrop(options?: RaindropTelemetryOptions): RaindropTelemetryIntegration;
1327
1384
 
1328
- export { eventMetadataFromChatRequest as $, type AISDKChatRequestLike as A, type BuildEventPatch as B, ContextManager as C, DEFAULT_MAX_TEXT_FIELD_CHARS as D, type EndSpanArgs as E, type TraceSpan as F, type TransformSpanHook as G, type WrappedAI as H, type IdentifyInput as I, type WrappedAISDK as J, _resetRaindropCallMetadataStorage as K, _resetWarnedMissingUserId as L, boundedStringify as M, capText as N, type OtlpAnyValue as O, type ParentToolContext as P, clearParentToolContext as Q, REDACTED_PLACEHOLDER as R, type SelfDiagnosticsOptions as S, TRUNCATION_MARKER as T, createRaindropAISDK as U, currentSpan as V, type WrapAISDKOptions as W, defaultTransformSpan as X, enterParentToolContext as Y, eventMetadata as Z, _resetParentToolContextStorage as _, type AISDKChatRequestMessageLike as a, getContextManager as a0, getCurrentParentToolContext as a1, getCurrentRaindropCallMetadata as a2, raindrop as a3, readRaindropCallMetadataFromArgs as a4, redactJsonAttributeValue as a5, redactSecretsInObject as a6, runWithParentToolContext as a7, runWithRaindropCallMetadata as a8, withCurrent as a9, type AISDKMessage as b, type AgentCallMetadata as c, type AgentWithMetadata as d, type Attachment as e, type ContextSpan as f, type CreateSpanArgs as g, DEFAULT_REDACT_ATTRIBUTE_KEYS as h, DEFAULT_SECRET_KEY_NAMES as i, type EventBuilder as j, type EventMetadataOptions as k, type OtlpSpan as l, type RaindropAISDKClient as m, type RaindropAISDKContext as n, type RaindropAISDKOptions as o, type RaindropCallMetadata as p, RaindropTelemetryIntegration as q, type RaindropTelemetryIntegrationOptions as r, type RaindropTelemetryOptions as s, type SelfDiagnosticsSignalDefinition as t, type SelfDiagnosticsSignalDefinitions as u, type SelfDiagnosticsTool as v, type SelfDiagnosticsToolInput as w, type SelfDiagnosticsToolOptions as x, type SelfDiagnosticsToolResult as y, type StartSpanArgs as z };
1385
+ export { enterParentToolContext as $, type AISDKChatRequestLike as A, type BuildEventPatch as B, ContextManager as C, DEFAULT_MAX_TEXT_FIELD_CHARS as D, type EndSpanArgs as E, type FeatureFlagValue as F, type StartSpanArgs as G, type TraceSpan as H, type IdentifyInput as I, type TransformSpanHook as J, type WrappedAI as K, type WrappedAISDK as L, _resetRaindropCallMetadataStorage as M, _resetWarnedMissingUserId as N, type OtlpAnyValue as O, type ParentToolContext as P, boundedStringify as Q, REDACTED_PLACEHOLDER as R, type SelfDiagnosticsOptions as S, TRUNCATION_MARKER as T, capText as U, clearParentToolContext as V, type WrapAISDKOptions as W, createRaindropAISDK as X, currentSpan as Y, defaultTransformSpan as Z, _resetParentToolContextStorage as _, type AISDKChatRequestMessageLike as a, eventMetadata as a0, eventMetadataFromChatRequest as a1, getContextManager as a2, getCurrentParentToolContext as a3, getCurrentRaindropCallMetadata as a4, normalizeFeatureFlags as a5, raindrop as a6, readRaindropCallMetadataFromArgs as a7, redactJsonAttributeValue as a8, redactSecretsInObject as a9, runWithParentToolContext as aa, runWithRaindropCallMetadata as ab, withCurrent as ac, type AISDKMessage as b, type AgentCallMetadata as c, type AgentWithMetadata as d, type Attachment as e, type ContextSpan as f, type CreateSpanArgs as g, DEFAULT_REDACT_ATTRIBUTE_KEYS as h, DEFAULT_SECRET_KEY_NAMES as i, type EventBuilder as j, type EventMetadataOptions as k, type FeatureFlags as l, type OtlpSpan as m, type RaindropAISDKClient as n, type RaindropAISDKContext as o, type RaindropAISDKOptions as p, type RaindropCallMetadata as q, RaindropTelemetryIntegration as r, type RaindropTelemetryIntegrationOptions as s, type RaindropTelemetryOptions as t, type SelfDiagnosticsSignalDefinition as u, type SelfDiagnosticsSignalDefinitions as v, type SelfDiagnosticsTool as w, type SelfDiagnosticsToolInput as x, type SelfDiagnosticsToolOptions as y, type SelfDiagnosticsToolResult as z };
@@ -1,3 +1,14 @@
1
+ type FeatureFlagValue = string | number | boolean;
2
+ type FeatureFlags = string[] | Record<string, FeatureFlagValue>;
3
+ /**
4
+ * Normalizes feature flags from the two accepted input forms into a
5
+ * canonical `Record<string, string>` ready for the wire payload.
6
+ *
7
+ * - Array form: `["a", "b"]` → `{"a": "true", "b": "true"}`
8
+ * - Object form: `{ a: "v2", b: true, c: 3 }` → `{"a": "v2", "b": "true", "c": "3"}`
9
+ */
10
+ declare function normalizeFeatureFlags(input: FeatureFlags): Record<string, string>;
11
+
1
12
  type OtlpAnyValue = {
2
13
  stringValue?: string;
3
14
  intValue?: string;
@@ -53,6 +64,7 @@ type Patch = {
53
64
  output?: string;
54
65
  model?: string;
55
66
  properties?: Record<string, unknown>;
67
+ featureFlags?: Record<string, string>;
56
68
  attachments?: Attachment$1[];
57
69
  isPending?: boolean;
58
70
  timestamp?: string;
@@ -153,6 +165,7 @@ declare class EventShipper$1 {
153
165
  output?: string;
154
166
  model?: string;
155
167
  properties?: Record<string, unknown>;
168
+ featureFlags?: Record<string, string>;
156
169
  userId?: string;
157
170
  }): Promise<void>;
158
171
  flush(): Promise<void>;
@@ -416,6 +429,42 @@ declare class TraceShipper$1 {
416
429
  shutdown(): Promise<void>;
417
430
  }
418
431
 
432
+ /**
433
+ * Run telemetry egress with OpenTelemetry tracing suppressed.
434
+ *
435
+ * Why this exists
436
+ * ---------------
437
+ * Raindrop integrations ship spans/events over HTTP with the global `fetch`
438
+ * (see {@link ../http.ts `postJson`}). When the host app also runs an OTel
439
+ * fetch/undici instrumentation — e.g. `@vercel/otel`'s `registerOTel`, which
440
+ * every Eve agent installs — that instrumentation wraps *our own* telemetry
441
+ * POSTs in a `fetch POST <endpoint>` span. Those spans are then handed to the
442
+ * very exporter that issued the request, so they get shipped right back to
443
+ * Raindrop and Workshop as standalone "runs" (and, because each export issues
444
+ * another fetch, they feed back on themselves). The result is a run list
445
+ * flooded with `fetch POST .../v1/traces`, `.../events/track_partial` and
446
+ * `.../live` entries that drown out the real agent turns — especially with
447
+ * sub-agents, where every sandbox runs its own instrumentation.
448
+ *
449
+ * The OTel-blessed fix is to mark the active context as "tracing suppressed"
450
+ * around the request; instrumentations check `isTracingSuppressed` and return
451
+ * a no-op span instead of recording one. We do this through a hook stashed on
452
+ * `globalThis` by the Node entrypoint ({@link ../index.node.ts}) so that:
453
+ * - `@opentelemetry/api` / `@opentelemetry/core` stay *optional* — core never
454
+ * hard-depends on them, and the hook is simply absent when they (and thus
455
+ * any instrumentation to suppress) are not installed; and
456
+ * - the browser bundle never pulls in `node:module`, mirroring how core
457
+ * injects `AsyncLocalStorage` via `RAINDROP_ASYNC_LOCAL_STORAGE`.
458
+ *
459
+ * When no hook is present the callback runs unchanged, so suppression is a
460
+ * best-effort no-op rather than a hard requirement.
461
+ */
462
+ /** Hook signature: run `fn` with OTel tracing suppressed, returning its value. */
463
+ type SuppressTracingHook = <T>(fn: () => T) => T;
464
+ declare global {
465
+ var RAINDROP_SUPPRESS_TRACING: SuppressTracingHook | undefined;
466
+ }
467
+
419
468
  type ParentSpanContext = {
420
469
  traceIdB64: string;
421
470
  spanIdB64: string;
@@ -527,6 +576,7 @@ type RaindropTelemetryIntegrationOptions = {
527
576
  eventName?: string;
528
577
  convoId?: string;
529
578
  properties?: Record<string, unknown>;
579
+ featureFlags?: Record<string, string>;
530
580
  };
531
581
  };
532
582
  declare class RaindropTelemetryIntegration implements TelemetryIntegration {
@@ -803,6 +853,8 @@ type EventMetadataOptions = {
803
853
  eventName?: string;
804
854
  /** Additional properties to merge with wrap-time properties */
805
855
  properties?: Record<string, unknown>;
856
+ /** Feature flags to attach to this event (merged with wrap-time flags; call-time wins) */
857
+ featureFlags?: FeatureFlags;
806
858
  };
807
859
  /**
808
860
  * Creates metadata for use with the AI SDK's `experimental_telemetry.metadata` option.
@@ -1006,6 +1058,7 @@ type RaindropAISDKContext = {
1006
1058
  eventName?: string;
1007
1059
  convoId?: string;
1008
1060
  properties?: Record<string, unknown>;
1061
+ featureFlags?: FeatureFlags;
1009
1062
  attachments?: Attachment[];
1010
1063
  };
1011
1064
 
@@ -1015,6 +1068,7 @@ type BuildEventPatch = {
1015
1068
  output?: string;
1016
1069
  model?: string;
1017
1070
  properties?: Record<string, unknown>;
1071
+ featureFlags?: Record<string, string>;
1018
1072
  attachments?: Attachment[];
1019
1073
  };
1020
1074
  /**
@@ -1179,6 +1233,7 @@ type EventPatch = {
1179
1233
  output?: string;
1180
1234
  model?: string;
1181
1235
  properties?: Record<string, unknown>;
1236
+ featureFlags?: Record<string, string>;
1182
1237
  attachments?: Attachment[];
1183
1238
  isPending?: boolean;
1184
1239
  timestamp?: string;
@@ -1211,10 +1266,12 @@ type RaindropAISDKClient = {
1211
1266
  patch(eventId: string, patch: EventPatch): Promise<void>;
1212
1267
  addAttachments(eventId: string, attachments: Attachment[]): Promise<void>;
1213
1268
  setProperties(eventId: string, properties: Record<string, unknown>): Promise<void>;
1269
+ setFeatureFlags(eventId: string, featureFlags: FeatureFlags): Promise<void>;
1214
1270
  finish(eventId: string, patch: {
1215
1271
  output?: string;
1216
1272
  model?: string;
1217
1273
  properties?: Record<string, unknown>;
1274
+ featureFlags?: Record<string, string>;
1218
1275
  }): Promise<void>;
1219
1276
  };
1220
1277
  /**
@@ -1325,4 +1382,4 @@ type RaindropTelemetryOptions = RaindropAISDKOptions & {
1325
1382
  */
1326
1383
  declare function raindrop(options?: RaindropTelemetryOptions): RaindropTelemetryIntegration;
1327
1384
 
1328
- export { eventMetadataFromChatRequest as $, type AISDKChatRequestLike as A, type BuildEventPatch as B, ContextManager as C, DEFAULT_MAX_TEXT_FIELD_CHARS as D, type EndSpanArgs as E, type TraceSpan as F, type TransformSpanHook as G, type WrappedAI as H, type IdentifyInput as I, type WrappedAISDK as J, _resetRaindropCallMetadataStorage as K, _resetWarnedMissingUserId as L, boundedStringify as M, capText as N, type OtlpAnyValue as O, type ParentToolContext as P, clearParentToolContext as Q, REDACTED_PLACEHOLDER as R, type SelfDiagnosticsOptions as S, TRUNCATION_MARKER as T, createRaindropAISDK as U, currentSpan as V, type WrapAISDKOptions as W, defaultTransformSpan as X, enterParentToolContext as Y, eventMetadata as Z, _resetParentToolContextStorage as _, type AISDKChatRequestMessageLike as a, getContextManager as a0, getCurrentParentToolContext as a1, getCurrentRaindropCallMetadata as a2, raindrop as a3, readRaindropCallMetadataFromArgs as a4, redactJsonAttributeValue as a5, redactSecretsInObject as a6, runWithParentToolContext as a7, runWithRaindropCallMetadata as a8, withCurrent as a9, type AISDKMessage as b, type AgentCallMetadata as c, type AgentWithMetadata as d, type Attachment as e, type ContextSpan as f, type CreateSpanArgs as g, DEFAULT_REDACT_ATTRIBUTE_KEYS as h, DEFAULT_SECRET_KEY_NAMES as i, type EventBuilder as j, type EventMetadataOptions as k, type OtlpSpan as l, type RaindropAISDKClient as m, type RaindropAISDKContext as n, type RaindropAISDKOptions as o, type RaindropCallMetadata as p, RaindropTelemetryIntegration as q, type RaindropTelemetryIntegrationOptions as r, type RaindropTelemetryOptions as s, type SelfDiagnosticsSignalDefinition as t, type SelfDiagnosticsSignalDefinitions as u, type SelfDiagnosticsTool as v, type SelfDiagnosticsToolInput as w, type SelfDiagnosticsToolOptions as x, type SelfDiagnosticsToolResult as y, type StartSpanArgs as z };
1385
+ export { enterParentToolContext as $, type AISDKChatRequestLike as A, type BuildEventPatch as B, ContextManager as C, DEFAULT_MAX_TEXT_FIELD_CHARS as D, type EndSpanArgs as E, type FeatureFlagValue as F, type StartSpanArgs as G, type TraceSpan as H, type IdentifyInput as I, type TransformSpanHook as J, type WrappedAI as K, type WrappedAISDK as L, _resetRaindropCallMetadataStorage as M, _resetWarnedMissingUserId as N, type OtlpAnyValue as O, type ParentToolContext as P, boundedStringify as Q, REDACTED_PLACEHOLDER as R, type SelfDiagnosticsOptions as S, TRUNCATION_MARKER as T, capText as U, clearParentToolContext as V, type WrapAISDKOptions as W, createRaindropAISDK as X, currentSpan as Y, defaultTransformSpan as Z, _resetParentToolContextStorage as _, type AISDKChatRequestMessageLike as a, eventMetadata as a0, eventMetadataFromChatRequest as a1, getContextManager as a2, getCurrentParentToolContext as a3, getCurrentRaindropCallMetadata as a4, normalizeFeatureFlags as a5, raindrop as a6, readRaindropCallMetadataFromArgs as a7, redactJsonAttributeValue as a8, redactSecretsInObject as a9, runWithParentToolContext as aa, runWithRaindropCallMetadata as ab, withCurrent as ac, type AISDKMessage as b, type AgentCallMetadata as c, type AgentWithMetadata as d, type Attachment as e, type ContextSpan as f, type CreateSpanArgs as g, DEFAULT_REDACT_ATTRIBUTE_KEYS as h, DEFAULT_SECRET_KEY_NAMES as i, type EventBuilder as j, type EventMetadataOptions as k, type FeatureFlags as l, type OtlpSpan as m, type RaindropAISDKClient as n, type RaindropAISDKContext as o, type RaindropAISDKOptions as p, type RaindropCallMetadata as q, RaindropTelemetryIntegration as r, type RaindropTelemetryIntegrationOptions as s, type RaindropTelemetryOptions as t, type SelfDiagnosticsSignalDefinition as u, type SelfDiagnosticsSignalDefinitions as v, type SelfDiagnosticsTool as w, type SelfDiagnosticsToolInput as x, type SelfDiagnosticsToolOptions as y, type SelfDiagnosticsToolResult as z };