@raindrop-ai/ai-sdk 0.0.2 → 0.0.4

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.js CHANGED
@@ -86,7 +86,7 @@ async function postJson(url, body, headers, opts) {
86
86
  // package.json
87
87
  var package_default = {
88
88
  name: "@raindrop-ai/ai-sdk",
89
- version: "0.0.2"};
89
+ version: "0.0.4"};
90
90
 
91
91
  // src/internal/version.ts
92
92
  var libraryName = package_default.name;
@@ -133,19 +133,30 @@ var EventShipper = class {
133
133
  return this.debug;
134
134
  }
135
135
  async patch(eventId, patch) {
136
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
136
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
137
137
  if (!this.enabled) return;
138
138
  if (!eventId) return;
139
- const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
140
- const existing = (_b = this.buffers.get(eventId)) != null ? _b : {};
139
+ if (this.debug) {
140
+ console.log("[raindrop-ai/ai-sdk] queue patch", {
141
+ eventId,
142
+ userId: patch.userId,
143
+ eventName: patch.eventName,
144
+ hasInput: typeof patch.input === "string" && patch.input.length > 0,
145
+ hasOutput: typeof patch.output === "string" && patch.output.length > 0,
146
+ attachments: (_b = (_a = patch.attachments) == null ? void 0 : _a.length) != null ? _b : 0,
147
+ isPending: patch.isPending
148
+ });
149
+ }
150
+ const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
151
+ const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
141
152
  const merged = mergePatches(existing, patch);
142
- merged.isPending = (_e = (_d = (_c = patch.isPending) != null ? _c : existing.isPending) != null ? _d : sticky.isPending) != null ? _e : true;
153
+ merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
143
154
  this.buffers.set(eventId, merged);
144
155
  this.sticky.set(eventId, {
145
- userId: (_f = merged.userId) != null ? _f : sticky.userId,
146
- convoId: (_g = merged.convoId) != null ? _g : sticky.convoId,
147
- eventName: (_h = merged.eventName) != null ? _h : sticky.eventName,
148
- isPending: (_i = merged.isPending) != null ? _i : sticky.isPending
156
+ userId: (_h = merged.userId) != null ? _h : sticky.userId,
157
+ convoId: (_i = merged.convoId) != null ? _i : sticky.convoId,
158
+ eventName: (_j = merged.eventName) != null ? _j : sticky.eventName,
159
+ isPending: (_k = merged.isPending) != null ? _k : sticky.isPending
149
160
  });
150
161
  const t = this.timers.get(eventId);
151
162
  if (t) clearTimeout(t);
@@ -242,7 +253,7 @@ var EventShipper = class {
242
253
  }
243
254
  }
244
255
  async flushOne(eventId) {
245
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
256
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
246
257
  if (!this.enabled) return;
247
258
  const timer = this.timers.get(eventId);
248
259
  if (timer) {
@@ -280,6 +291,24 @@ var EventShipper = class {
280
291
  is_pending: ((_i = (_h = accumulated.isPending) != null ? _h : sticky.isPending) != null ? _i : true) !== false
281
292
  };
282
293
  const url = `${this.baseUrl}events/track_partial`;
294
+ if (this.debug) {
295
+ console.log("[raindrop-ai/ai-sdk] sending track_partial", {
296
+ eventId,
297
+ eventName,
298
+ userId,
299
+ isPending: payload.is_pending,
300
+ inputPreview: typeof accumulated.input === "string" ? accumulated.input.slice(0, 120) : void 0,
301
+ outputPreview: typeof accumulated.output === "string" ? accumulated.output.slice(0, 120) : void 0,
302
+ attachments: (_k = (_j = accumulated.attachments) == null ? void 0 : _j.length) != null ? _k : 0,
303
+ attachmentKinds: (_m = (_l = accumulated.attachments) == null ? void 0 : _l.map((a) => ({
304
+ type: a.type,
305
+ role: a.role,
306
+ name: a.name,
307
+ valuePreview: a.value.slice(0, 60)
308
+ }))) != null ? _m : [],
309
+ endpoint: url
310
+ });
311
+ }
283
312
  const p = postJson(
284
313
  url,
285
314
  payload,
@@ -522,6 +551,12 @@ var TraceShipper = class {
522
551
  const batch = this.queue.splice(0, this.maxBatchSize);
523
552
  const body = buildExportTraceServiceRequest(batch);
524
553
  const url = `${this.baseUrl}traces`;
554
+ if (this.debug) {
555
+ console.log("[raindrop-ai/ai-sdk] sending traces batch", {
556
+ spans: batch.length,
557
+ endpoint: url
558
+ });
559
+ }
525
560
  const p = postJson(
526
561
  url,
527
562
  body,
@@ -849,7 +884,13 @@ function isAgentClass(value) {
849
884
  function extractModel(result) {
850
885
  if (!isRecord(result)) return void 0;
851
886
  const model = result["model"];
852
- return typeof model === "string" && model.length ? model : void 0;
887
+ if (typeof model === "string" && model.length) return model;
888
+ const response = result["response"];
889
+ if (isRecord(response)) {
890
+ const modelId = response["modelId"];
891
+ if (typeof modelId === "string" && modelId.length) return modelId;
892
+ }
893
+ return void 0;
853
894
  }
854
895
  function extractFinishReason(result) {
855
896
  if (!isRecord(result)) return void 0;
@@ -859,6 +900,174 @@ function extractFinishReason(result) {
859
900
  }
860
901
  return void 0;
861
902
  }
903
+ function bytesToBase64(bytes) {
904
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
905
+ let binary = "";
906
+ for (let i = 0; i < bytes.length; i++) {
907
+ binary += String.fromCharCode(bytes[i]);
908
+ }
909
+ if (typeof btoa === "function") return btoa(binary);
910
+ return "";
911
+ }
912
+ function asDataUrl(value, mediaType) {
913
+ if (value instanceof URL) return value.toString();
914
+ if (typeof value === "string") {
915
+ if (value.startsWith("data:")) return value;
916
+ if (value.startsWith("http://") || value.startsWith("https://")) return value;
917
+ return `data:${mediaType};base64,${value}`;
918
+ }
919
+ if (value instanceof Uint8Array) {
920
+ const base64 = bytesToBase64(value);
921
+ if (!base64) return void 0;
922
+ return `data:${mediaType};base64,${base64}`;
923
+ }
924
+ if (value instanceof ArrayBuffer) {
925
+ const base64 = bytesToBase64(new Uint8Array(value));
926
+ if (!base64) return void 0;
927
+ return `data:${mediaType};base64,${base64}`;
928
+ }
929
+ return void 0;
930
+ }
931
+ function dataPartToAttachmentValue(value) {
932
+ if (typeof value === "string") return value;
933
+ if (value instanceof URL) return value.toString();
934
+ if (value instanceof Uint8Array) return `[binary:${value.byteLength} bytes]`;
935
+ if (value instanceof ArrayBuffer) return `[binary:${value.byteLength} bytes]`;
936
+ return void 0;
937
+ }
938
+ function attachmentMediaType(part) {
939
+ if (typeof part["mediaType"] === "string") return part["mediaType"];
940
+ if (typeof part["mimeType"] === "string") return part["mimeType"];
941
+ const file = part["file"];
942
+ if (isRecord(file)) {
943
+ if (typeof file["mediaType"] === "string") return file["mediaType"];
944
+ if (typeof file["mimeType"] === "string") return file["mimeType"];
945
+ }
946
+ return void 0;
947
+ }
948
+ function attachmentName(part) {
949
+ if (typeof part["filename"] === "string") return part["filename"];
950
+ if (typeof part["name"] === "string") return part["name"];
951
+ const file = part["file"];
952
+ if (isRecord(file)) {
953
+ if (typeof file["filename"] === "string") return file["filename"];
954
+ if (typeof file["name"] === "string") return file["name"];
955
+ }
956
+ return void 0;
957
+ }
958
+ function attachmentData(part) {
959
+ if ("data" in part) return part["data"];
960
+ const file = part["file"];
961
+ if (isRecord(file)) {
962
+ if ("file_data" in file) return file["file_data"];
963
+ if ("data" in file) return file["data"];
964
+ }
965
+ return void 0;
966
+ }
967
+ function contentPartToAttachment(part, role) {
968
+ var _a, _b, _c;
969
+ const partType = part["type"];
970
+ if (typeof partType !== "string") return void 0;
971
+ if (partType === "image") {
972
+ const mediaType = (_a = attachmentMediaType(part)) != null ? _a : "image/png";
973
+ const value = asDataUrl(part["image"], mediaType);
974
+ if (!value) return void 0;
975
+ return { type: "image", role, value };
976
+ }
977
+ if (partType === "image_url") {
978
+ const imageUrlPart = part["image_url"];
979
+ const imageUrlValue = isRecord(imageUrlPart) ? imageUrlPart["url"] : imageUrlPart;
980
+ const value = asDataUrl(imageUrlValue, "image/png");
981
+ if (!value) return void 0;
982
+ return { type: "image", role, value };
983
+ }
984
+ if (partType === "file") {
985
+ const mediaType = attachmentMediaType(part);
986
+ const data = attachmentData(part);
987
+ const isImage = (mediaType == null ? void 0 : mediaType.startsWith("image/")) === true;
988
+ const value = isImage && mediaType ? asDataUrl(data, mediaType) : dataPartToAttachmentValue(data);
989
+ if (!value) return void 0;
990
+ const name = (_c = (_b = attachmentName(part)) != null ? _b : mediaType) != null ? _c : "file";
991
+ return { type: isImage ? "image" : "text", role, name, value };
992
+ }
993
+ return void 0;
994
+ }
995
+ function attachmentsFromContent(content, role) {
996
+ if (!Array.isArray(content)) return void 0;
997
+ const attachments = [];
998
+ for (const part of content) {
999
+ if (!isRecord(part)) continue;
1000
+ const attachment = contentPartToAttachment(part, role);
1001
+ if (attachment) attachments.push(attachment);
1002
+ }
1003
+ return attachments.length ? attachments : void 0;
1004
+ }
1005
+ function generatedFileToAttachment(file) {
1006
+ var _a, _b, _c, _d;
1007
+ const mediaType = typeof file["mediaType"] === "string" ? file["mediaType"] : typeof file["mimeType"] === "string" ? file["mimeType"] : void 0;
1008
+ const data = (_d = (_c = (_b = (_a = file["base64Data"]) != null ? _a : file["base64"]) != null ? _b : file["uint8ArrayData"]) != null ? _c : file["uint8Array"]) != null ? _d : file["data"];
1009
+ const isImage = (mediaType == null ? void 0 : mediaType.startsWith("image/")) === true;
1010
+ const value = isImage && mediaType ? asDataUrl(data, mediaType) : dataPartToAttachmentValue(data);
1011
+ if (!value) return void 0;
1012
+ const name = typeof file["filename"] === "string" ? file["filename"] : typeof file["name"] === "string" ? file["name"] : mediaType != null ? mediaType : "file";
1013
+ return {
1014
+ type: isImage ? "image" : "text",
1015
+ role: "output",
1016
+ name,
1017
+ value
1018
+ };
1019
+ }
1020
+ async function outputAttachmentsFromFiles(files) {
1021
+ let resolvedFiles = files;
1022
+ if (resolvedFiles && (typeof resolvedFiles === "object" || typeof resolvedFiles === "function") && typeof resolvedFiles.then === "function") {
1023
+ try {
1024
+ resolvedFiles = await resolvedFiles;
1025
+ } catch (e) {
1026
+ return void 0;
1027
+ }
1028
+ }
1029
+ if (!Array.isArray(resolvedFiles)) return void 0;
1030
+ const attachments = [];
1031
+ for (const file of resolvedFiles) {
1032
+ if (!isRecord(file)) continue;
1033
+ const attachment = generatedFileToAttachment(file);
1034
+ if (attachment) attachments.push(attachment);
1035
+ }
1036
+ return attachments.length ? attachments : void 0;
1037
+ }
1038
+ function extractTextFromMessageContent(content) {
1039
+ if (typeof content === "string") return content;
1040
+ if (!Array.isArray(content)) return void 0;
1041
+ let result = "";
1042
+ for (const part of content) {
1043
+ if (!isRecord(part) || part["type"] !== "text" || typeof part["text"] !== "string") continue;
1044
+ result += part["text"];
1045
+ }
1046
+ return result.length ? result : void 0;
1047
+ }
1048
+ function extractInputAttachmentsFromArgs(args) {
1049
+ if (!isRecord(args)) return void 0;
1050
+ const messages = args["messages"];
1051
+ if (!Array.isArray(messages)) return void 0;
1052
+ for (let i = messages.length - 1; i >= 0; i--) {
1053
+ const message = messages[i];
1054
+ if (!isRecord(message) || message["role"] !== "user") continue;
1055
+ return attachmentsFromContent(message["content"], "input");
1056
+ }
1057
+ return void 0;
1058
+ }
1059
+ async function extractOutputAttachmentsFromResult(result) {
1060
+ if (!isRecord(result)) return void 0;
1061
+ const fileAttachments = await outputAttachmentsFromFiles(result["files"]);
1062
+ if (fileAttachments == null ? void 0 : fileAttachments.length) return fileAttachments;
1063
+ const responseMessages = extractResponseMessages(result);
1064
+ for (let i = responseMessages.length - 1; i >= 0; i--) {
1065
+ const message = responseMessages[i];
1066
+ if (!isRecord(message) || message["role"] !== "assistant") continue;
1067
+ return attachmentsFromContent(message["content"], "output");
1068
+ }
1069
+ return attachmentsFromContent(result["content"], "output");
1070
+ }
862
1071
  function lastUserMessageTextFromArgs(args) {
863
1072
  var _a;
864
1073
  if (!isRecord(args)) return void 0;
@@ -868,7 +1077,8 @@ function lastUserMessageTextFromArgs(args) {
868
1077
  const message = messages[i];
869
1078
  if (!isRecord(message) || message["role"] !== "user") continue;
870
1079
  const content = message["content"];
871
- if (typeof content === "string") return content;
1080
+ const text = extractTextFromMessageContent(content);
1081
+ if (text !== void 0) return text;
872
1082
  return (_a = safeJsonWithUint8(content)) != null ? _a : String(content);
873
1083
  }
874
1084
  return void 0;
@@ -883,7 +1093,8 @@ function extractInputFromArgs(args) {
883
1093
  const last = messages[messages.length - 1];
884
1094
  if (isRecord(last)) {
885
1095
  const content = last["content"];
886
- if (typeof content === "string") return content;
1096
+ const text = extractTextFromMessageContent(content);
1097
+ if (text !== void 0) return text;
887
1098
  const asJson = safeJson(content);
888
1099
  if (asJson) return asJson;
889
1100
  }
@@ -917,7 +1128,9 @@ function extractResponseMessages(result) {
917
1128
  if (!isRecord(result)) return [];
918
1129
  const response = result["response"];
919
1130
  if (isRecord(response) && Array.isArray(response["messages"])) {
920
- return response["messages"].filter((message) => isRecord(message) && typeof message["role"] === "string" && "content" in message).map((message) => message);
1131
+ return response["messages"].filter(
1132
+ (message) => isRecord(message) && typeof message["role"] === "string" && "content" in message
1133
+ ).map((message) => message);
921
1134
  }
922
1135
  const steps = result["steps"];
923
1136
  if (Array.isArray(steps) && steps.length > 0) {
@@ -925,7 +1138,9 @@ function extractResponseMessages(result) {
925
1138
  if (isRecord(lastStep) && isRecord(lastStep["response"])) {
926
1139
  const responseMessages = lastStep["response"]["messages"];
927
1140
  if (Array.isArray(responseMessages)) {
928
- return responseMessages.filter((message) => isRecord(message) && typeof message["role"] === "string" && "content" in message).map((message) => message);
1141
+ return responseMessages.filter(
1142
+ (message) => isRecord(message) && typeof message["role"] === "string" && "content" in message
1143
+ ).map((message) => message);
929
1144
  }
930
1145
  }
931
1146
  }
@@ -975,9 +1190,11 @@ function opName(operationId, functionId) {
975
1190
  function toOtlpAttr(key, value) {
976
1191
  if (value === void 0 || value === null) return void 0;
977
1192
  if (typeof value === "string") return attrString(key, value);
978
- if (typeof value === "number") return Number.isInteger(value) ? attrInt(key, value) : attrDouble(key, value);
1193
+ if (typeof value === "number")
1194
+ return Number.isInteger(value) ? attrInt(key, value) : attrDouble(key, value);
979
1195
  if (typeof value === "boolean") return attrBool(key, value);
980
- if (Array.isArray(value) && value.every((v) => typeof v === "string")) return attrStringArray(key, value);
1196
+ if (Array.isArray(value) && value.every((v) => typeof v === "string"))
1197
+ return attrStringArray(key, value);
981
1198
  const asJson = safeJsonWithUint8(value);
982
1199
  return asJson ? attrString(key, asJson) : void 0;
983
1200
  }
@@ -1023,13 +1240,31 @@ function attrsFromSettings(args) {
1023
1240
  function attrsFromGenAiRequest(options) {
1024
1241
  if (!isRecord(options)) return [];
1025
1242
  return [
1026
- attrDouble("gen_ai.request.frequency_penalty", typeof options["frequencyPenalty"] === "number" ? options["frequencyPenalty"] : void 0),
1027
- attrInt("gen_ai.request.max_tokens", typeof options["maxOutputTokens"] === "number" ? options["maxOutputTokens"] : void 0),
1028
- attrDouble("gen_ai.request.presence_penalty", typeof options["presencePenalty"] === "number" ? options["presencePenalty"] : void 0),
1243
+ attrDouble(
1244
+ "gen_ai.request.frequency_penalty",
1245
+ typeof options["frequencyPenalty"] === "number" ? options["frequencyPenalty"] : void 0
1246
+ ),
1247
+ attrInt(
1248
+ "gen_ai.request.max_tokens",
1249
+ typeof options["maxOutputTokens"] === "number" ? options["maxOutputTokens"] : void 0
1250
+ ),
1251
+ attrDouble(
1252
+ "gen_ai.request.presence_penalty",
1253
+ typeof options["presencePenalty"] === "number" ? options["presencePenalty"] : void 0
1254
+ ),
1029
1255
  ...Array.isArray(options["stopSequences"]) && options["stopSequences"].every((x) => typeof x === "string") ? [attrStringArray("gen_ai.request.stop_sequences", options["stopSequences"])] : [],
1030
- attrDouble("gen_ai.request.temperature", typeof options["temperature"] === "number" ? options["temperature"] : void 0),
1031
- attrInt("gen_ai.request.top_k", typeof options["topK"] === "number" ? options["topK"] : void 0),
1032
- attrDouble("gen_ai.request.top_p", typeof options["topP"] === "number" ? options["topP"] : void 0)
1256
+ attrDouble(
1257
+ "gen_ai.request.temperature",
1258
+ typeof options["temperature"] === "number" ? options["temperature"] : void 0
1259
+ ),
1260
+ attrInt(
1261
+ "gen_ai.request.top_k",
1262
+ typeof options["topK"] === "number" ? options["topK"] : void 0
1263
+ ),
1264
+ attrDouble(
1265
+ "gen_ai.request.top_p",
1266
+ typeof options["topP"] === "number" ? options["topP"] : void 0
1267
+ )
1033
1268
  ];
1034
1269
  }
1035
1270
 
@@ -1077,6 +1312,7 @@ function wrapAISDK(aiSDK, deps) {
1077
1312
  const agentClasses = /* @__PURE__ */ new Set(["ToolLoopAgent"]);
1078
1313
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1079
1314
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
1315
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
1080
1316
  const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
1081
1317
  return new Proxy(proxyTarget, {
1082
1318
  get(target, prop, receiver) {
@@ -1130,14 +1366,27 @@ function wrapAISDK(aiSDK, deps) {
1130
1366
  ]
1131
1367
  }) : void 0;
1132
1368
  const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
1133
- const wrapCtx = { eventId, telemetry, sendTraces, traceShipper: deps.traceShipper, rootParentForChildren };
1369
+ const wrapCtx = {
1370
+ eventId,
1371
+ telemetry,
1372
+ sendTraces,
1373
+ traceShipper: deps.traceShipper,
1374
+ rootParentForChildren
1375
+ };
1134
1376
  const toolCalls = [];
1135
1377
  const argWithWrappedTools = wrapTools(arg, wrapCtx, toolCalls);
1136
- const argWithWrappedModel = wrapModel(argWithWrappedTools, aiSDK, outerOperationId, wrapCtx);
1378
+ const argWithWrappedModel = wrapModel(
1379
+ argWithWrappedTools,
1380
+ aiSDK,
1381
+ outerOperationId,
1382
+ wrapCtx
1383
+ );
1137
1384
  const finalize = async (result, error) => {
1138
1385
  var _a3, _b3, _c2;
1139
1386
  const usage = extractUsage(result);
1140
1387
  const model = extractModel(result);
1388
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(arg) : void 0;
1389
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
1141
1390
  const baseMessages = coerceMessagesFromArgs(arg);
1142
1391
  const responseMessages = extractResponseMessages(result);
1143
1392
  const allMessages = [...baseMessages, ...responseMessages];
@@ -1150,7 +1399,7 @@ function wrapAISDK(aiSDK, deps) {
1150
1399
  output: defaultOutput,
1151
1400
  model,
1152
1401
  properties: ctx.properties,
1153
- attachments: ctx.attachments
1402
+ attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
1154
1403
  };
1155
1404
  const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
1156
1405
  const patch = mergeBuildEventPatch(defaultPatch, built);
@@ -1170,7 +1419,10 @@ function wrapAISDK(aiSDK, deps) {
1170
1419
  attrString("ai.response.finishReason", finishReason),
1171
1420
  operation === "generateObject" || operation === "streamObject" ? attrString("ai.response.object", output) : attrString("ai.response.text", output),
1172
1421
  attrString("ai.response.toolCalls", resultToolCalls),
1173
- attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
1422
+ attrString(
1423
+ "ai.response.providerMetadata",
1424
+ safeJsonWithUint8(providerMetadata)
1425
+ )
1174
1426
  ],
1175
1427
  attrInt("ai.usage.promptTokens", usage == null ? void 0 : usage.inputTokens),
1176
1428
  attrInt("ai.usage.completionTokens", usage == null ? void 0 : usage.outputTokens),
@@ -1180,7 +1432,12 @@ function wrapAISDK(aiSDK, deps) {
1180
1432
  attrInt("ai.usage.reasoningTokens", reasoningTokens),
1181
1433
  attrInt("ai.usage.cachedInputTokens", cachedInputTokens),
1182
1434
  attrInt("ai.toolCall.count", toolCalls.length),
1183
- ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
1435
+ ...error ? [
1436
+ attrString(
1437
+ "error.message",
1438
+ error instanceof Error ? error.message : String(error)
1439
+ )
1440
+ ] : []
1184
1441
  ]
1185
1442
  });
1186
1443
  }
@@ -1196,12 +1453,18 @@ function wrapAISDK(aiSDK, deps) {
1196
1453
  attachments: patch.attachments,
1197
1454
  isPending: false
1198
1455
  }).catch((err) => {
1199
- if (debug) console.warn(`[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`);
1456
+ if (debug)
1457
+ console.warn(
1458
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1459
+ );
1200
1460
  });
1201
1461
  }
1202
1462
  };
1203
1463
  const callOriginal = async (...args) => {
1204
- return await original.call(aiSDK, ...args);
1464
+ return await original.call(
1465
+ aiSDK,
1466
+ ...args
1467
+ );
1205
1468
  };
1206
1469
  const runWithContext = async (fn) => {
1207
1470
  if (!rootSpan) return await fn();
@@ -1215,7 +1478,10 @@ function wrapAISDK(aiSDK, deps) {
1215
1478
  try {
1216
1479
  await finalize(result);
1217
1480
  } catch (err) {
1218
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1481
+ if (debug)
1482
+ console.warn(
1483
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1484
+ );
1219
1485
  }
1220
1486
  });
1221
1487
  try {
@@ -1242,7 +1508,10 @@ function wrapAISDK(aiSDK, deps) {
1242
1508
  try {
1243
1509
  await finalize(void 0, error);
1244
1510
  } catch (err) {
1245
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1511
+ if (debug)
1512
+ console.warn(
1513
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1514
+ );
1246
1515
  }
1247
1516
  throw error;
1248
1517
  }
@@ -1256,14 +1525,20 @@ function wrapAISDK(aiSDK, deps) {
1256
1525
  try {
1257
1526
  await finalize(result);
1258
1527
  } catch (err) {
1259
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1528
+ if (debug)
1529
+ console.warn(
1530
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1531
+ );
1260
1532
  }
1261
1533
  return result;
1262
1534
  } catch (error) {
1263
1535
  try {
1264
1536
  await finalize(void 0, error);
1265
1537
  } catch (err) {
1266
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1538
+ if (debug)
1539
+ console.warn(
1540
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1541
+ );
1267
1542
  }
1268
1543
  throw error;
1269
1544
  }
@@ -1315,6 +1590,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1315
1590
  var _a, _b;
1316
1591
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1317
1592
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
1593
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
1318
1594
  return async (...callArgs) => {
1319
1595
  var _a2, _b2, _c, _d;
1320
1596
  const callParams = callArgs[0];
@@ -1358,13 +1634,28 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1358
1634
  ]
1359
1635
  }) : void 0;
1360
1636
  const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
1361
- const wrapCtx = { eventId, telemetry, sendTraces, traceShipper: deps.traceShipper, rootParentForChildren };
1637
+ const wrapCtx = {
1638
+ eventId,
1639
+ telemetry,
1640
+ sendTraces,
1641
+ traceShipper: deps.traceShipper,
1642
+ rootParentForChildren
1643
+ };
1362
1644
  const toolCalls = [];
1363
- const callParamsWithWrappedTools = callParams ? wrapTools(callParams, wrapCtx, toolCalls) : callParams;
1645
+ const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
1646
+ const mergedArgsWithWrappedModel = wrapModel(
1647
+ mergedArgsWithWrappedTools,
1648
+ aiSDK,
1649
+ outerOperationId,
1650
+ wrapCtx
1651
+ );
1652
+ const callParamsWithWrappedToolsAndModel = mergedArgsWithWrappedModel != null ? mergedArgsWithWrappedModel : {};
1364
1653
  const finalize = async (result, error) => {
1365
1654
  var _a3, _b3, _c2;
1366
1655
  const usage = extractUsage(result);
1367
1656
  const model = extractModel(result);
1657
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(mergedArgs) : void 0;
1658
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
1368
1659
  const baseMessages = coerceMessagesFromArgs(mergedArgs);
1369
1660
  const responseMessages = extractResponseMessages(result);
1370
1661
  const allMessages = [...baseMessages, ...responseMessages];
@@ -1375,7 +1666,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1375
1666
  output: outputText,
1376
1667
  model,
1377
1668
  properties: ctx.properties,
1378
- attachments: ctx.attachments
1669
+ attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
1379
1670
  };
1380
1671
  const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
1381
1672
  const patch = mergeBuildEventPatch(defaultPatch, built);
@@ -1405,7 +1696,12 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1405
1696
  attrInt("ai.usage.reasoningTokens", reasoningTokens),
1406
1697
  attrInt("ai.usage.cachedInputTokens", cachedInputTokens),
1407
1698
  attrInt("ai.toolCall.count", toolCalls.length),
1408
- ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
1699
+ ...error ? [
1700
+ attrString(
1701
+ "error.message",
1702
+ error instanceof Error ? error.message : String(error)
1703
+ )
1704
+ ] : []
1409
1705
  ]
1410
1706
  });
1411
1707
  }
@@ -1429,7 +1725,10 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1429
1725
  attachments: patch.attachments,
1430
1726
  isPending: false
1431
1727
  }).catch((err) => {
1432
- if (debug) console.warn(`[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`);
1728
+ if (debug)
1729
+ console.warn(
1730
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1731
+ );
1433
1732
  });
1434
1733
  } else if (debug) {
1435
1734
  console.log(`[raindrop-ai/ai-sdk] Agent ${operation} sendEvents=false, skipping event`);
@@ -1451,7 +1750,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1451
1750
  }
1452
1751
  try {
1453
1752
  const result = await runWithContext(async () => {
1454
- return await generate.call(instance, callParamsWithWrappedTools);
1753
+ return await generate.call(instance, callParamsWithWrappedToolsAndModel);
1455
1754
  });
1456
1755
  if (debug) {
1457
1756
  console.log(`[raindrop-ai/ai-sdk] Agent ${operation} completed, finalizing...`);
@@ -1459,14 +1758,20 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1459
1758
  try {
1460
1759
  await finalize(result);
1461
1760
  } catch (err) {
1462
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1761
+ if (debug)
1762
+ console.warn(
1763
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1764
+ );
1463
1765
  }
1464
1766
  return result;
1465
1767
  } catch (error) {
1466
1768
  try {
1467
1769
  await finalize(void 0, error);
1468
1770
  } catch (err) {
1469
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1771
+ if (debug)
1772
+ console.warn(
1773
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1774
+ );
1470
1775
  }
1471
1776
  throw error;
1472
1777
  }
@@ -1476,6 +1781,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1476
1781
  var _a, _b;
1477
1782
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1478
1783
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
1784
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
1479
1785
  return async (...callArgs) => {
1480
1786
  var _a2, _b2, _c, _d;
1481
1787
  const callParams = callArgs[0];
@@ -1519,13 +1825,28 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1519
1825
  ]
1520
1826
  }) : void 0;
1521
1827
  const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
1522
- const wrapCtx = { eventId, telemetry, sendTraces, traceShipper: deps.traceShipper, rootParentForChildren };
1828
+ const wrapCtx = {
1829
+ eventId,
1830
+ telemetry,
1831
+ sendTraces,
1832
+ traceShipper: deps.traceShipper,
1833
+ rootParentForChildren
1834
+ };
1523
1835
  const toolCalls = [];
1524
- const callParamsWithWrappedTools = callParams ? wrapTools(callParams, wrapCtx, toolCalls) : callParams;
1836
+ const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
1837
+ const mergedArgsWithWrappedModel = wrapModel(
1838
+ mergedArgsWithWrappedTools,
1839
+ aiSDK,
1840
+ outerOperationId,
1841
+ wrapCtx
1842
+ );
1843
+ const callParamsWithWrappedToolsAndModel = mergedArgsWithWrappedModel != null ? mergedArgsWithWrappedModel : {};
1525
1844
  const finalize = async (result, error) => {
1526
1845
  var _a3, _b3, _c2;
1527
1846
  const usage = extractUsage(result);
1528
1847
  const model = extractModel(result);
1848
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(mergedArgs) : void 0;
1849
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
1529
1850
  const baseMessages = coerceMessagesFromArgs(mergedArgs);
1530
1851
  const responseMessages = extractResponseMessages(result);
1531
1852
  const allMessages = [...baseMessages, ...responseMessages];
@@ -1536,7 +1857,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1536
1857
  output: outputText,
1537
1858
  model,
1538
1859
  properties: ctx.properties,
1539
- attachments: ctx.attachments
1860
+ attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
1540
1861
  };
1541
1862
  const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
1542
1863
  const patch = mergeBuildEventPatch(defaultPatch, built);
@@ -1566,7 +1887,12 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1566
1887
  attrInt("ai.usage.reasoningTokens", reasoningTokens),
1567
1888
  attrInt("ai.usage.cachedInputTokens", cachedInputTokens),
1568
1889
  attrInt("ai.toolCall.count", toolCalls.length),
1569
- ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
1890
+ ...error ? [
1891
+ attrString(
1892
+ "error.message",
1893
+ error instanceof Error ? error.message : String(error)
1894
+ )
1895
+ ] : []
1570
1896
  ]
1571
1897
  });
1572
1898
  }
@@ -1590,7 +1916,10 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1590
1916
  attachments: patch.attachments,
1591
1917
  isPending: false
1592
1918
  }).catch((err) => {
1593
- if (debug) console.warn(`[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`);
1919
+ if (debug)
1920
+ console.warn(
1921
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1922
+ );
1594
1923
  });
1595
1924
  } else if (debug) {
1596
1925
  console.log(`[raindrop-ai/ai-sdk] Agent ${operation} sendEvents=false, skipping event`);
@@ -1610,16 +1939,22 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1610
1939
  eventName: ctx.eventName
1611
1940
  });
1612
1941
  }
1613
- const callParamsWithOnFinish = wrapOnFinish(callParamsWithWrappedTools != null ? callParamsWithWrappedTools : {}, async (result) => {
1614
- if (debug) {
1615
- console.log(`[raindrop-ai/ai-sdk] Agent ${operation} onFinish callback, finalizing...`);
1616
- }
1617
- try {
1618
- await finalize(result);
1619
- } catch (err) {
1620
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1942
+ const callParamsWithOnFinish = wrapOnFinish(
1943
+ callParamsWithWrappedToolsAndModel != null ? callParamsWithWrappedToolsAndModel : {},
1944
+ async (result) => {
1945
+ if (debug) {
1946
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} onFinish callback, finalizing...`);
1947
+ }
1948
+ try {
1949
+ await finalize(result);
1950
+ } catch (err) {
1951
+ if (debug)
1952
+ console.warn(
1953
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1954
+ );
1955
+ }
1621
1956
  }
1622
- });
1957
+ );
1623
1958
  try {
1624
1959
  const result = await runWithContext(async () => {
1625
1960
  return await stream.call(instance, callParamsWithOnFinish);
@@ -1629,7 +1964,10 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1629
1964
  try {
1630
1965
  await finalize(void 0, error);
1631
1966
  } catch (err) {
1632
- if (debug) console.warn(`[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`);
1967
+ if (debug)
1968
+ console.warn(
1969
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
1970
+ );
1633
1971
  }
1634
1972
  throw error;
1635
1973
  }
@@ -1672,7 +2010,9 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
1672
2010
  if (!span) return;
1673
2011
  if (error) {
1674
2012
  ctx.traceShipper.endSpan(span, {
1675
- attributes: [attrString("error.message", error instanceof Error ? error.message : String(error))]
2013
+ attributes: [
2014
+ attrString("error.message", error instanceof Error ? error.message : String(error))
2015
+ ]
1676
2016
  });
1677
2017
  } else {
1678
2018
  ctx.traceShipper.endSpan(span, {
@@ -1729,7 +2069,11 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
1729
2069
  };
1730
2070
  if (!toolSpan) return await run();
1731
2071
  return await runWithParentSpanContext(
1732
- { traceIdB64: toolSpan.ids.traceIdB64, spanIdB64: toolSpan.ids.spanIdB64, eventId: ctx.eventId },
2072
+ {
2073
+ traceIdB64: toolSpan.ids.traceIdB64,
2074
+ spanIdB64: toolSpan.ids.spanIdB64,
2075
+ eventId: ctx.eventId
2076
+ },
1733
2077
  run
1734
2078
  );
1735
2079
  })();
@@ -1768,7 +2112,15 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
1768
2112
  if (span) endDoGenerateSpan(span, result, modelInfo, ctx);
1769
2113
  return result;
1770
2114
  } catch (error) {
1771
- if (span) ctx.traceShipper.endSpan(span, { attributes: [attrString("error.message", error instanceof Error ? error.message : String(error))] });
2115
+ if (span)
2116
+ ctx.traceShipper.endSpan(span, {
2117
+ attributes: [
2118
+ attrString(
2119
+ "error.message",
2120
+ error instanceof Error ? error.message : String(error)
2121
+ )
2122
+ ]
2123
+ });
1772
2124
  throw error;
1773
2125
  }
1774
2126
  };
@@ -1796,7 +2148,12 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
1796
2148
  } catch (error) {
1797
2149
  if (span)
1798
2150
  ctx.traceShipper.endSpan(span, {
1799
- attributes: [attrString("error.message", error instanceof Error ? error.message : String(error))]
2151
+ attributes: [
2152
+ attrString(
2153
+ "error.message",
2154
+ error instanceof Error ? error.message : String(error)
2155
+ )
2156
+ ]
1800
2157
  });
1801
2158
  throw error;
1802
2159
  }
@@ -1822,11 +2179,17 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
1822
2179
  ...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
1823
2180
  attrString("ai.response.finishReason", finishReason),
1824
2181
  attrString("ai.response.text", activeText.length ? activeText : void 0),
1825
- attrString("ai.response.toolCalls", safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)),
2182
+ attrString(
2183
+ "ai.response.toolCalls",
2184
+ safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
2185
+ ),
1826
2186
  attrString("ai.response.id", responseId),
1827
2187
  attrString("ai.response.model", responseModelId),
1828
2188
  attrString("ai.response.timestamp", responseTimestampIso),
1829
- attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
2189
+ attrString(
2190
+ "ai.response.providerMetadata",
2191
+ safeJsonWithUint8(providerMetadata)
2192
+ )
1830
2193
  ],
1831
2194
  attrInt("ai.usage.inputTokens", inputTokens),
1832
2195
  attrInt("ai.usage.outputTokens", outputTokens),
@@ -1838,7 +2201,12 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
1838
2201
  ...msToFirstChunk !== void 0 ? [attrInt("ai.stream.msToFirstChunk", msToFirstChunk)] : [],
1839
2202
  ...msToFinish !== void 0 ? [attrInt("ai.stream.msToFinish", msToFinish)] : [],
1840
2203
  ...avgOutTokensPerSecond !== void 0 ? [attrDouble("ai.stream.avgOutputTokensPerSecond", avgOutTokensPerSecond)] : [],
1841
- ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
2204
+ ...error ? [
2205
+ attrString(
2206
+ "error.message",
2207
+ error instanceof Error ? error.message : String(error)
2208
+ )
2209
+ ] : []
1842
2210
  ]
1843
2211
  });
1844
2212
  };
@@ -1855,15 +2223,20 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
1855
2223
  if (firstChunkMs === void 0) firstChunkMs = Date.now();
1856
2224
  if (isRecord(value)) {
1857
2225
  const type = value["type"];
1858
- if (type === "text-delta" && typeof value["textDelta"] === "string") activeText += value["textDelta"];
1859
- if (type === "finish" && typeof value["finishReason"] === "string") finishReason = value["finishReason"];
2226
+ if (type === "text-delta" && typeof value["textDelta"] === "string")
2227
+ activeText += value["textDelta"];
2228
+ if (type === "finish" && typeof value["finishReason"] === "string")
2229
+ finishReason = value["finishReason"];
1860
2230
  if (type === "tool-call") toolCallsLocal.push(value);
1861
2231
  if ("response" in value && isRecord(value["response"])) {
1862
2232
  const response = value["response"];
1863
2233
  if (typeof response["id"] === "string") responseId = response["id"];
1864
- if (typeof response["modelId"] === "string") responseModelId = response["modelId"];
1865
- if (response["timestamp"] instanceof Date) responseTimestampIso = response["timestamp"].toISOString();
1866
- else if (typeof response["timestamp"] === "string") responseTimestampIso = response["timestamp"];
2234
+ if (typeof response["modelId"] === "string")
2235
+ responseModelId = response["modelId"];
2236
+ if (response["timestamp"] instanceof Date)
2237
+ responseTimestampIso = response["timestamp"].toISOString();
2238
+ else if (typeof response["timestamp"] === "string")
2239
+ responseTimestampIso = response["timestamp"];
1867
2240
  }
1868
2241
  if ("usage" in value) usage = value["usage"];
1869
2242
  if ("providerMetadata" in value) providerMetadata = value["providerMetadata"];
@@ -1905,7 +2278,11 @@ function startDoGenerateSpan(operationId, options, modelInfo, parent, ctx) {
1905
2278
  attrString("ai.telemetry.functionId", (_b = ctx.telemetry) == null ? void 0 : _b.functionId),
1906
2279
  attrString("ai.model.provider", modelInfo.provider),
1907
2280
  attrString("ai.model.id", modelInfo.modelId),
1908
- ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [attrString("ai.prompt.messages", promptJson), attrStringArray("ai.prompt.tools", toolsJson), attrString("ai.prompt.toolChoice", toolChoiceJson)],
2281
+ ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [
2282
+ attrString("ai.prompt.messages", promptJson),
2283
+ attrStringArray("ai.prompt.tools", toolsJson),
2284
+ attrString("ai.prompt.toolChoice", toolChoiceJson)
2285
+ ],
1909
2286
  attrString("gen_ai.system", modelInfo.provider),
1910
2287
  attrString("gen_ai.request.model", modelInfo.modelId),
1911
2288
  ...attrsFromGenAiRequest(options)
@@ -1946,7 +2323,10 @@ function endDoGenerateSpan(span, result, modelInfo, ctx) {
1946
2323
  ...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
1947
2324
  attrString("ai.response.finishReason", finishReason),
1948
2325
  attrString("ai.response.text", extractTextFromLmContent(content)),
1949
- attrString("ai.response.toolCalls", safeJsonWithUint8(extractToolCallsFromLmContent(content))),
2326
+ attrString(
2327
+ "ai.response.toolCalls",
2328
+ safeJsonWithUint8(extractToolCallsFromLmContent(content))
2329
+ ),
1950
2330
  attrString("ai.response.id", responseId),
1951
2331
  attrString("ai.response.model", responseModelId),
1952
2332
  attrString("ai.response.timestamp", responseTimestampIso),
@@ -1980,7 +2360,11 @@ function startDoStreamSpan(operationId, options, modelInfo, parent, ctx) {
1980
2360
  attrString("ai.telemetry.functionId", (_b = ctx.telemetry) == null ? void 0 : _b.functionId),
1981
2361
  attrString("ai.model.provider", modelInfo.provider),
1982
2362
  attrString("ai.model.id", modelInfo.modelId),
1983
- ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [attrString("ai.prompt.messages", promptJson), attrStringArray("ai.prompt.tools", toolsJson), attrString("ai.prompt.toolChoice", toolChoiceJson)],
2363
+ ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [
2364
+ attrString("ai.prompt.messages", promptJson),
2365
+ attrStringArray("ai.prompt.tools", toolsJson),
2366
+ attrString("ai.prompt.toolChoice", toolChoiceJson)
2367
+ ],
1984
2368
  attrString("gen_ai.system", modelInfo.provider),
1985
2369
  attrString("gen_ai.request.model", modelInfo.modelId),
1986
2370
  ...attrsFromGenAiRequest(options)
@@ -2032,6 +2416,13 @@ function mergeBuildEventPatch(defaults, override) {
2032
2416
  attachments: override.attachments !== void 0 ? [...(_g = defaults.attachments) != null ? _g : [], ...(_h = override.attachments) != null ? _h : []] : defaults.attachments
2033
2417
  };
2034
2418
  }
2419
+ function mergeAttachments(...groups) {
2420
+ const merged = [];
2421
+ for (const group of groups) {
2422
+ if (group == null ? void 0 : group.length) merged.push(...group);
2423
+ }
2424
+ return merged.length ? merged : void 0;
2425
+ }
2035
2426
  function extractNestedTokens(usage, key) {
2036
2427
  if (!isRecord(usage)) return void 0;
2037
2428
  const val = usage[key];
@@ -2051,23 +2442,30 @@ function eventMetadata(options) {
2051
2442
  if (options.properties) result["raindrop.properties"] = JSON.stringify(options.properties);
2052
2443
  return result;
2053
2444
  }
2445
+ function envDebugEnabled() {
2446
+ var _a;
2447
+ if (typeof process === "undefined") return false;
2448
+ const flag = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
2449
+ return flag === "1" || flag === "true";
2450
+ }
2054
2451
  function createRaindropAISDK(opts) {
2055
2452
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2056
2453
  const eventsEnabled = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
2057
2454
  const tracesEnabled = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
2455
+ const envDebug = envDebugEnabled();
2058
2456
  const eventShipper = new EventShipper({
2059
2457
  writeKey: opts.writeKey,
2060
2458
  endpoint: opts.endpoint,
2061
2459
  enabled: eventsEnabled,
2062
- debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true,
2460
+ debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
2063
2461
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
2064
2462
  });
2065
2463
  const traceShipper = new TraceShipper({
2066
2464
  writeKey: opts.writeKey,
2067
2465
  endpoint: opts.endpoint,
2068
2466
  enabled: tracesEnabled,
2069
- debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true,
2070
- debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true,
2467
+ debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
2468
+ debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true || envDebug,
2071
2469
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
2072
2470
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
2073
2471
  maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize