@raindrop-ai/ai-sdk 0.0.19-beta.4 → 0.0.20

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.
@@ -0,0 +1,3948 @@
1
+ // ../core/dist/chunk-H6VSZSLN.js
2
+ function getCrypto() {
3
+ const c = globalThis.crypto;
4
+ return c;
5
+ }
6
+ function randomBytes(length) {
7
+ const cryptoObj = getCrypto();
8
+ const out = new Uint8Array(length);
9
+ if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
10
+ cryptoObj.getRandomValues(out);
11
+ return out;
12
+ }
13
+ for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
14
+ return out;
15
+ }
16
+ function randomUUID() {
17
+ const cryptoObj = getCrypto();
18
+ if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
19
+ return cryptoObj.randomUUID();
20
+ }
21
+ const b = randomBytes(16);
22
+ b[6] = b[6] & 15 | 64;
23
+ b[8] = b[8] & 63 | 128;
24
+ const hex = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
25
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
26
+ }
27
+ function base64Encode(bytes) {
28
+ const maybeBuffer = globalThis.Buffer;
29
+ if (maybeBuffer) {
30
+ return maybeBuffer.from(bytes).toString("base64");
31
+ }
32
+ let binary = "";
33
+ for (let i2 = 0; i2 < bytes.length; i2++) {
34
+ binary += String.fromCharCode(bytes[i2]);
35
+ }
36
+ const btoaFn = globalThis.btoa;
37
+ if (typeof btoaFn === "function") return btoaFn(binary);
38
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
39
+ let out = "";
40
+ let i = 0;
41
+ while (i < binary.length) {
42
+ const c1 = binary.charCodeAt(i++) & 255;
43
+ const c2 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
44
+ const c3 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
45
+ const e1 = c1 >> 2;
46
+ const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
47
+ const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
48
+ const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
49
+ out += alphabet.charAt(e1);
50
+ out += alphabet.charAt(e2);
51
+ out += e3 === 64 ? "=" : alphabet.charAt(e3);
52
+ out += e4 === 64 ? "=" : alphabet.charAt(e4);
53
+ }
54
+ return out;
55
+ }
56
+ function wait(ms) {
57
+ return new Promise((resolve) => setTimeout(resolve, ms));
58
+ }
59
+ function formatEndpoint(endpoint) {
60
+ if (!endpoint) return void 0;
61
+ return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
62
+ }
63
+ function parseRetryAfter(headers) {
64
+ var _a;
65
+ const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
66
+ if (!value) return void 0;
67
+ const asNumber = Number(value);
68
+ if (value.trim() !== "" && !Number.isNaN(asNumber)) return asNumber * 1e3;
69
+ const asDate = new Date(value).getTime();
70
+ if (!Number.isNaN(asDate)) {
71
+ const delta = asDate - Date.now();
72
+ return delta > 0 ? delta : 0;
73
+ }
74
+ return void 0;
75
+ }
76
+ function getRetryDelayMs(attemptNumber, previousError) {
77
+ if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
78
+ const v = previousError.retryAfterMs;
79
+ if (typeof v === "number") return Math.max(0, v);
80
+ }
81
+ if (attemptNumber <= 1) return 0;
82
+ const base = 500;
83
+ const factor = Math.pow(2, attemptNumber - 2);
84
+ return base * factor;
85
+ }
86
+ async function withRetry(operation, opName2, opts) {
87
+ const prefix = opts.sdkName ? `[raindrop-ai/${opts.sdkName}]` : "[raindrop-ai/core]";
88
+ let lastError = void 0;
89
+ for (let attemptNumber = 1; attemptNumber <= opts.maxAttempts; attemptNumber++) {
90
+ if (attemptNumber > 1) {
91
+ const delay = getRetryDelayMs(attemptNumber, lastError);
92
+ if (opts.debug) {
93
+ console.warn(
94
+ `${prefix} ${opName2} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`
95
+ );
96
+ }
97
+ if (delay > 0) await wait(delay);
98
+ } else if (opts.debug) {
99
+ console.log(`${prefix} ${opName2} attempt ${attemptNumber}/${opts.maxAttempts}`);
100
+ }
101
+ try {
102
+ return await operation();
103
+ } catch (err) {
104
+ lastError = err;
105
+ if (opts.debug) {
106
+ const msg = err instanceof Error ? err.message : String(err);
107
+ console.warn(
108
+ `${prefix} ${opName2} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
109
+ );
110
+ }
111
+ if (lastError && typeof lastError === "object" && "retryable" in lastError && !lastError.retryable)
112
+ break;
113
+ if (attemptNumber === opts.maxAttempts) break;
114
+ }
115
+ }
116
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
117
+ }
118
+ async function postJson(url, body, headers, opts) {
119
+ const opName2 = `POST ${url}`;
120
+ await withRetry(
121
+ async () => {
122
+ const resp = await fetch(url, {
123
+ method: "POST",
124
+ headers: {
125
+ "Content-Type": "application/json",
126
+ ...headers
127
+ },
128
+ body: JSON.stringify(body)
129
+ });
130
+ if (!resp.ok) {
131
+ const text = await resp.text().catch(() => "");
132
+ const err = new Error(
133
+ `HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
134
+ );
135
+ const retryAfterMs = parseRetryAfter(resp.headers);
136
+ if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
137
+ err.retryable = resp.status === 429 || resp.status >= 500;
138
+ throw err;
139
+ }
140
+ },
141
+ opName2,
142
+ opts
143
+ );
144
+ }
145
+ var SpanStatusCode = {
146
+ ERROR: 2
147
+ };
148
+ function createSpanIds(parent) {
149
+ const traceId = parent ? parent.traceIdB64 : base64Encode(randomBytes(16));
150
+ const spanId = base64Encode(randomBytes(8));
151
+ return {
152
+ traceIdB64: traceId,
153
+ spanIdB64: spanId,
154
+ parentSpanIdB64: parent ? parent.spanIdB64 : void 0
155
+ };
156
+ }
157
+ function nowUnixNanoString() {
158
+ return Date.now().toString() + "000000";
159
+ }
160
+ function attrString(key, value) {
161
+ if (value === void 0) return void 0;
162
+ return { key, value: { stringValue: value } };
163
+ }
164
+ function attrInt(key, value) {
165
+ if (value === void 0) return void 0;
166
+ if (!Number.isFinite(value)) return void 0;
167
+ return { key, value: { intValue: String(Math.trunc(value)) } };
168
+ }
169
+ function attrDouble(key, value) {
170
+ if (value === void 0) return void 0;
171
+ if (!Number.isFinite(value)) return void 0;
172
+ return { key, value: { doubleValue: value } };
173
+ }
174
+ function attrBool(key, value) {
175
+ if (value === void 0) return void 0;
176
+ return { key, value: { boolValue: value } };
177
+ }
178
+ function attrStringArray(key, values) {
179
+ if (!values || values.length === 0) return void 0;
180
+ return {
181
+ key,
182
+ value: {
183
+ arrayValue: {
184
+ values: values.filter((v) => typeof v === "string").map((v) => ({ stringValue: v }))
185
+ }
186
+ }
187
+ };
188
+ }
189
+ function buildOtlpSpan(args) {
190
+ const attrs = args.attributes.filter((x) => x !== void 0);
191
+ const span = {
192
+ traceId: args.ids.traceIdB64,
193
+ spanId: args.ids.spanIdB64,
194
+ name: args.name,
195
+ startTimeUnixNano: args.startTimeUnixNano,
196
+ endTimeUnixNano: args.endTimeUnixNano
197
+ };
198
+ if (args.ids.parentSpanIdB64) span.parentSpanId = args.ids.parentSpanIdB64;
199
+ if (attrs.length) span.attributes = attrs;
200
+ if (args.status) span.status = args.status;
201
+ return span;
202
+ }
203
+ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", serviceVersion = "0.0.0") {
204
+ return {
205
+ resourceSpans: [
206
+ {
207
+ resource: {
208
+ attributes: [{ key: "service.name", value: { stringValue: serviceName } }]
209
+ },
210
+ scopeSpans: [
211
+ {
212
+ scope: { name: serviceName, version: serviceVersion },
213
+ spans
214
+ }
215
+ ]
216
+ }
217
+ ]
218
+ };
219
+ }
220
+ function mergePatches(target, source) {
221
+ var _a, _b, _c, _d;
222
+ const out = { ...target, ...source };
223
+ if (target.properties || source.properties) {
224
+ out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
225
+ }
226
+ if (target.attachments || source.attachments) {
227
+ out.attachments = [...(_c = target.attachments) != null ? _c : [], ...(_d = source.attachments) != null ? _d : []];
228
+ }
229
+ return out;
230
+ }
231
+ var EventShipper = class {
232
+ constructor(opts) {
233
+ this.buffers = /* @__PURE__ */ new Map();
234
+ this.sticky = /* @__PURE__ */ new Map();
235
+ this.timers = /* @__PURE__ */ new Map();
236
+ this.inFlight = /* @__PURE__ */ new Set();
237
+ var _a, _b, _c, _d, _e, _f, _g;
238
+ this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
239
+ this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
240
+ this.enabled = opts.enabled !== false;
241
+ this.debug = opts.debug;
242
+ this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
243
+ this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
244
+ this.prefix = `[raindrop-ai/${this.sdkName}]`;
245
+ this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
246
+ const isNode = typeof process !== "undefined" && typeof process.version === "string";
247
+ this.context = {
248
+ library: {
249
+ name: (_f = opts.libraryName) != null ? _f : "@raindrop-ai/core",
250
+ version: (_g = opts.libraryVersion) != null ? _g : "0.0.0"
251
+ },
252
+ metadata: {
253
+ jsRuntime: isNode ? "node" : "web",
254
+ ...isNode ? { nodeVersion: process.version } : {}
255
+ }
256
+ };
257
+ }
258
+ isDebugEnabled() {
259
+ return this.debug;
260
+ }
261
+ authHeaders() {
262
+ return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
263
+ }
264
+ async patch(eventId, patch) {
265
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
266
+ if (!this.enabled) return;
267
+ if (!eventId || !eventId.trim()) return;
268
+ if (this.debug) {
269
+ console.log(`${this.prefix} queue patch`, {
270
+ eventId,
271
+ userId: patch.userId,
272
+ convoId: patch.convoId,
273
+ eventName: patch.eventName,
274
+ hasInput: typeof patch.input === "string" && patch.input.length > 0,
275
+ hasOutput: typeof patch.output === "string" && patch.output.length > 0,
276
+ attachments: (_b = (_a = patch.attachments) == null ? void 0 : _a.length) != null ? _b : 0,
277
+ isPending: patch.isPending
278
+ });
279
+ }
280
+ const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
281
+ const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
282
+ const merged = mergePatches(existing, patch);
283
+ merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
284
+ this.buffers.set(eventId, merged);
285
+ this.sticky.set(eventId, {
286
+ userId: (_h = merged.userId) != null ? _h : sticky.userId,
287
+ convoId: (_i = merged.convoId) != null ? _i : sticky.convoId,
288
+ eventName: (_j = merged.eventName) != null ? _j : sticky.eventName,
289
+ isPending: (_k = merged.isPending) != null ? _k : sticky.isPending
290
+ });
291
+ const t = this.timers.get(eventId);
292
+ if (t) clearTimeout(t);
293
+ if (merged.isPending === false) {
294
+ await this.flushOne(eventId);
295
+ return;
296
+ }
297
+ const timeout = setTimeout(() => {
298
+ void this.flushOne(eventId).catch(() => {
299
+ });
300
+ }, this.partialFlushMs);
301
+ this.timers.set(eventId, timeout);
302
+ }
303
+ async finish(eventId, patch) {
304
+ await this.patch(eventId, { ...patch, isPending: false });
305
+ }
306
+ async flush() {
307
+ if (!this.enabled) return;
308
+ const ids = [...this.buffers.keys()];
309
+ await Promise.all(ids.map((id) => this.flushOne(id)));
310
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
311
+ })));
312
+ }
313
+ async shutdown() {
314
+ for (const t of this.timers.values()) clearTimeout(t);
315
+ this.timers.clear();
316
+ await this.flush();
317
+ }
318
+ async trackSignal(signal) {
319
+ var _a, _b;
320
+ if (!this.enabled) return;
321
+ const body = [
322
+ {
323
+ event_id: signal.eventId,
324
+ signal_name: signal.name,
325
+ signal_type: (_a = signal.type) != null ? _a : "default",
326
+ timestamp: signal.timestamp,
327
+ sentiment: signal.sentiment,
328
+ attachment_id: signal.attachmentId,
329
+ properties: {
330
+ ...(_b = signal.properties) != null ? _b : {},
331
+ ...signal.comment ? { comment: signal.comment } : {},
332
+ ...signal.after ? { after: signal.after } : {}
333
+ }
334
+ }
335
+ ];
336
+ const url = `${this.baseUrl}signals/track`;
337
+ try {
338
+ await postJson(url, body, this.authHeaders(), {
339
+ maxAttempts: 3,
340
+ debug: this.debug,
341
+ sdkName: this.sdkName
342
+ });
343
+ } catch (err) {
344
+ const msg = err instanceof Error ? err.message : String(err);
345
+ console.warn(`${this.prefix} failed to send signal (dropping): ${msg}`);
346
+ }
347
+ }
348
+ async identify(users) {
349
+ if (!this.enabled) return;
350
+ const list = Array.isArray(users) ? users : [users];
351
+ const body = list.filter((user) => {
352
+ if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
353
+ if (this.debug) {
354
+ console.warn(`${this.prefix} skipping identify: missing userId`);
355
+ }
356
+ return false;
357
+ }
358
+ return true;
359
+ }).map((user) => {
360
+ var _a;
361
+ return {
362
+ user_id: user.userId,
363
+ traits: (_a = user.traits) != null ? _a : {}
364
+ };
365
+ });
366
+ if (body.length === 0) return;
367
+ const url = `${this.baseUrl}users/identify`;
368
+ try {
369
+ await postJson(url, body, this.authHeaders(), {
370
+ maxAttempts: 3,
371
+ debug: this.debug,
372
+ sdkName: this.sdkName
373
+ });
374
+ } catch (err) {
375
+ const msg = err instanceof Error ? err.message : String(err);
376
+ console.warn(`${this.prefix} failed to send identify (dropping): ${msg}`);
377
+ }
378
+ }
379
+ async flushOne(eventId) {
380
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
381
+ if (!this.enabled) return;
382
+ const timer = this.timers.get(eventId);
383
+ if (timer) {
384
+ clearTimeout(timer);
385
+ this.timers.delete(eventId);
386
+ }
387
+ const accumulated = this.buffers.get(eventId);
388
+ this.buffers.delete(eventId);
389
+ if (!accumulated) return;
390
+ const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
391
+ const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
392
+ const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
393
+ if (!userId) {
394
+ if (this.debug) {
395
+ console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
396
+ }
397
+ this.sticky.delete(eventId);
398
+ return;
399
+ }
400
+ const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
401
+ const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
402
+ const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
403
+ const payload = {
404
+ event_id: eventId,
405
+ user_id: userId,
406
+ event: eventName,
407
+ timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
408
+ ai_data: {
409
+ input: accumulated.input,
410
+ output: accumulated.output,
411
+ model: accumulated.model,
412
+ convo_id: convoId
413
+ },
414
+ properties: {
415
+ ...restProperties,
416
+ ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
417
+ $context: this.context
418
+ },
419
+ attachments: accumulated.attachments,
420
+ is_pending: isPending
421
+ };
422
+ const url = `${this.baseUrl}events/track_partial`;
423
+ if (this.debug) {
424
+ console.log(`${this.prefix} sending track_partial`, {
425
+ eventId,
426
+ eventName,
427
+ userId,
428
+ convoId,
429
+ isPending,
430
+ inputPreview: typeof accumulated.input === "string" ? accumulated.input.slice(0, 120) : void 0,
431
+ outputPreview: typeof accumulated.output === "string" ? accumulated.output.slice(0, 120) : void 0,
432
+ attachments: (_k = (_j = accumulated.attachments) == null ? void 0 : _j.length) != null ? _k : 0,
433
+ attachmentKinds: (_m = (_l = accumulated.attachments) == null ? void 0 : _l.map((a) => ({
434
+ type: a.type,
435
+ role: a.role,
436
+ name: a.name,
437
+ valuePreview: a.value.slice(0, 60)
438
+ }))) != null ? _m : [],
439
+ endpoint: url
440
+ });
441
+ }
442
+ const p = postJson(url, payload, this.authHeaders(), {
443
+ maxAttempts: 3,
444
+ debug: this.debug,
445
+ sdkName: this.sdkName
446
+ });
447
+ this.inFlight.add(p);
448
+ try {
449
+ try {
450
+ await p;
451
+ if (this.debug) {
452
+ console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
453
+ }
454
+ } catch (err) {
455
+ const msg = err instanceof Error ? err.message : String(err);
456
+ console.warn(`${this.prefix} failed to send track_partial (dropping): ${msg}`);
457
+ }
458
+ } finally {
459
+ this.inFlight.delete(p);
460
+ }
461
+ if (!isPending) {
462
+ this.sticky.delete(eventId);
463
+ }
464
+ }
465
+ };
466
+ var TraceShipper = class {
467
+ constructor(opts) {
468
+ this.queue = [];
469
+ this.inFlight = /* @__PURE__ */ new Set();
470
+ var _a, _b, _c, _d, _e, _f, _g, _h;
471
+ this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
472
+ this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
473
+ this.enabled = opts.enabled !== false;
474
+ this.debug = opts.debug;
475
+ this.debugSpans = opts.debugSpans === true;
476
+ this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
477
+ this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
478
+ this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
479
+ this.sdkName = (_f = opts.sdkName) != null ? _f : "core";
480
+ this.prefix = `[raindrop-ai/${this.sdkName}]`;
481
+ this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
482
+ this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
483
+ }
484
+ isDebugEnabled() {
485
+ return this.debug;
486
+ }
487
+ authHeaders() {
488
+ return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
489
+ }
490
+ startSpan(args) {
491
+ var _a, _b;
492
+ const ids = createSpanIds(args.parent);
493
+ const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
494
+ const attrs = [
495
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
496
+ attrString("ai.operationId", args.operationId)
497
+ ];
498
+ if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
499
+ return { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
500
+ }
501
+ endSpan(span, extra) {
502
+ var _a, _b;
503
+ if (span.endTimeUnixNano) return;
504
+ span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
505
+ if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
506
+ span.attributes.push(...extra.attributes);
507
+ }
508
+ let status = extra == null ? void 0 : extra.status;
509
+ if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
510
+ const message = extra.error instanceof Error ? extra.error.message : String(extra.error);
511
+ status = { code: SpanStatusCode.ERROR, message };
512
+ }
513
+ const otlp = buildOtlpSpan({
514
+ ids: span.ids,
515
+ name: span.name,
516
+ startTimeUnixNano: span.startTimeUnixNano,
517
+ endTimeUnixNano: span.endTimeUnixNano,
518
+ attributes: span.attributes,
519
+ status
520
+ });
521
+ this.enqueue(otlp);
522
+ }
523
+ createSpan(args) {
524
+ var _a;
525
+ const ids = createSpanIds(args.parent);
526
+ const attrs = [
527
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
528
+ ];
529
+ if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
530
+ const otlp = buildOtlpSpan({
531
+ ids,
532
+ name: args.name,
533
+ startTimeUnixNano: args.startTimeUnixNano,
534
+ endTimeUnixNano: args.endTimeUnixNano,
535
+ attributes: attrs,
536
+ status: args.status
537
+ });
538
+ this.enqueue(otlp);
539
+ }
540
+ enqueue(span) {
541
+ if (!this.enabled) return;
542
+ if (this.debugSpans) {
543
+ const short = (s) => s ? s.slice(-8) : "none";
544
+ console.log(
545
+ `${this.prefix}[span] name=${span.name} trace=${short(span.traceId)} span=${short(span.spanId)} parent=${short(
546
+ span.parentSpanId
547
+ )}`
548
+ );
549
+ }
550
+ if (this.queue.length >= this.maxQueueSize) {
551
+ this.queue.shift();
552
+ }
553
+ this.queue.push(span);
554
+ if (this.queue.length >= this.maxBatchSize) {
555
+ void this.flush().catch(() => {
556
+ });
557
+ return;
558
+ }
559
+ if (!this.timer) {
560
+ this.timer = setTimeout(() => {
561
+ this.timer = void 0;
562
+ void this.flush().catch(() => {
563
+ });
564
+ }, this.flushIntervalMs);
565
+ }
566
+ }
567
+ async flush() {
568
+ if (!this.enabled) return;
569
+ if (this.timer) {
570
+ clearTimeout(this.timer);
571
+ this.timer = void 0;
572
+ }
573
+ while (this.queue.length > 0) {
574
+ const batch = this.queue.splice(0, this.maxBatchSize);
575
+ const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
576
+ const url = `${this.baseUrl}traces`;
577
+ if (this.debug) {
578
+ console.log(`${this.prefix} sending traces batch`, {
579
+ spans: batch.length,
580
+ endpoint: url
581
+ });
582
+ }
583
+ const p = postJson(url, body, this.authHeaders(), {
584
+ maxAttempts: 3,
585
+ debug: this.debug,
586
+ sdkName: this.sdkName
587
+ });
588
+ this.inFlight.add(p);
589
+ try {
590
+ try {
591
+ await p;
592
+ if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
593
+ } catch (err) {
594
+ const msg = err instanceof Error ? err.message : String(err);
595
+ console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`);
596
+ }
597
+ } finally {
598
+ this.inFlight.delete(p);
599
+ }
600
+ }
601
+ }
602
+ async shutdown() {
603
+ if (this.timer) {
604
+ clearTimeout(this.timer);
605
+ this.timer = void 0;
606
+ }
607
+ await this.flush();
608
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
609
+ })));
610
+ }
611
+ };
612
+ var NOOP_SPAN = {
613
+ traceIdB64: "",
614
+ spanIdB64: "",
615
+ eventId: "",
616
+ log() {
617
+ }
618
+ };
619
+ function getAsyncLocalStorageCtor() {
620
+ return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
621
+ }
622
+ var SynchronousContextStorage = class {
623
+ constructor() {
624
+ this._stack = [];
625
+ }
626
+ isEmpty() {
627
+ return this._stack.length === 0;
628
+ }
629
+ getStore() {
630
+ return this._stack[this._stack.length - 1];
631
+ }
632
+ run(store, callback) {
633
+ this._stack.push(store);
634
+ try {
635
+ return callback();
636
+ } finally {
637
+ this._stack.pop();
638
+ }
639
+ }
640
+ };
641
+ var ContextManager = class {
642
+ };
643
+ var RaindropContextManager = class extends ContextManager {
644
+ constructor() {
645
+ super();
646
+ this._fallback = null;
647
+ const Ctor = getAsyncLocalStorageCtor();
648
+ if (Ctor) {
649
+ this._storage = new Ctor();
650
+ return;
651
+ }
652
+ this._fallback = new SynchronousContextStorage();
653
+ this._storage = this._fallback;
654
+ }
655
+ maybeAdoptAsyncLocalStorage() {
656
+ if (!this._fallback || !this._fallback.isEmpty()) return;
657
+ const Ctor = getAsyncLocalStorageCtor();
658
+ if (!Ctor) return;
659
+ this._storage = new Ctor();
660
+ this._fallback = null;
661
+ }
662
+ isReady() {
663
+ return true;
664
+ }
665
+ getParentSpanIds() {
666
+ this.maybeAdoptAsyncLocalStorage();
667
+ const span = this._storage.getStore();
668
+ if (!span || span === NOOP_SPAN) return void 0;
669
+ return {
670
+ traceIdB64: span.traceIdB64,
671
+ spanIdB64: span.spanIdB64,
672
+ eventId: span.eventId
673
+ };
674
+ }
675
+ runInContext(span, callback) {
676
+ this.maybeAdoptAsyncLocalStorage();
677
+ return this._storage.run(span, callback);
678
+ }
679
+ getCurrentSpan() {
680
+ this.maybeAdoptAsyncLocalStorage();
681
+ return this._storage.getStore();
682
+ }
683
+ };
684
+ var _contextManager = null;
685
+ function getContextManager() {
686
+ if (!_contextManager) {
687
+ _contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
688
+ }
689
+ return _contextManager;
690
+ }
691
+ function currentSpan() {
692
+ var _a;
693
+ return (_a = getContextManager().getCurrentSpan()) != null ? _a : NOOP_SPAN;
694
+ }
695
+ function withCurrent(span, callback) {
696
+ return getContextManager().runInContext(span, callback);
697
+ }
698
+ async function getCurrentParentSpanContext() {
699
+ return getContextManager().getParentSpanIds();
700
+ }
701
+ async function runWithParentSpanContext(ctx, fn) {
702
+ const cm = getContextManager();
703
+ const span = {
704
+ traceIdB64: ctx.traceIdB64,
705
+ spanIdB64: ctx.spanIdB64,
706
+ eventId: ctx.eventId
707
+ };
708
+ return cm.runInContext(span, fn);
709
+ }
710
+ async function* asyncGeneratorWithCurrent(span, gen) {
711
+ let nextValue;
712
+ while (true) {
713
+ const result = await withCurrent(span, async () => {
714
+ try {
715
+ return await gen.next(nextValue);
716
+ } catch (e) {
717
+ return { value: void 0, done: true, error: e };
718
+ }
719
+ });
720
+ if ("error" in result && result.error !== void 0) {
721
+ throw result.error;
722
+ }
723
+ if (result.done) {
724
+ return result.value;
725
+ }
726
+ nextValue = yield result.value;
727
+ }
728
+ }
729
+
730
+ // package.json
731
+ var package_default = {
732
+ name: "@raindrop-ai/ai-sdk",
733
+ version: "0.0.20"};
734
+
735
+ // src/internal/version.ts
736
+ var libraryName = package_default.name;
737
+ var libraryVersion = package_default.version;
738
+
739
+ // src/internal/events.ts
740
+ var EventShipper2 = class extends EventShipper {
741
+ constructor(opts) {
742
+ var _a, _b, _c;
743
+ super({
744
+ ...opts,
745
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
746
+ libraryName: (_b = opts.libraryName) != null ? _b : libraryName,
747
+ libraryVersion: (_c = opts.libraryVersion) != null ? _c : libraryVersion
748
+ });
749
+ }
750
+ };
751
+
752
+ // src/internal/wrap/helpers.ts
753
+ function isRecord(value) {
754
+ return typeof value === "object" && value !== null;
755
+ }
756
+ function isFunction(value) {
757
+ return typeof value === "function";
758
+ }
759
+ function isModuleNamespace(obj) {
760
+ var _a;
761
+ if (!obj || typeof obj !== "object") return false;
762
+ const asObject = obj;
763
+ if (((_a = asObject.constructor) == null ? void 0 : _a.name) === "Module") return true;
764
+ try {
765
+ const keys = Object.keys(obj);
766
+ if (keys.length === 0) return false;
767
+ const descriptor = Object.getOwnPropertyDescriptor(obj, keys[0]);
768
+ if (!descriptor) return false;
769
+ const isWritable = "writable" in descriptor ? descriptor.writable : true;
770
+ return !descriptor.configurable && !isWritable;
771
+ } catch (e) {
772
+ return false;
773
+ }
774
+ }
775
+ function safeJson(value) {
776
+ try {
777
+ return JSON.stringify(value);
778
+ } catch (e) {
779
+ return void 0;
780
+ }
781
+ }
782
+ function safeJsonWithUint8(value) {
783
+ try {
784
+ return JSON.stringify(value, (_key, v) => {
785
+ if (v instanceof Uint8Array) return base64Encode(v);
786
+ return v;
787
+ });
788
+ } catch (e) {
789
+ return void 0;
790
+ }
791
+ }
792
+ function extractModelInfo(model) {
793
+ if (typeof model === "string") {
794
+ const slashIndex2 = model.indexOf("/");
795
+ if (slashIndex2 > 0 && slashIndex2 < model.length - 1) {
796
+ return {
797
+ provider: model.slice(0, slashIndex2),
798
+ modelId: model.slice(slashIndex2 + 1)
799
+ };
800
+ }
801
+ return { modelId: model };
802
+ }
803
+ if (!isRecord(model)) return {};
804
+ const provider = typeof model["provider"] === "string" ? model["provider"] : void 0;
805
+ let modelIdRaw;
806
+ if (typeof model["modelId"] === "string") {
807
+ modelIdRaw = model["modelId"];
808
+ } else if (typeof model["model"] === "string") {
809
+ modelIdRaw = model["model"];
810
+ }
811
+ if (!modelIdRaw) {
812
+ return { provider };
813
+ }
814
+ const slashIndex = modelIdRaw.indexOf("/");
815
+ if (!provider && slashIndex > 0 && slashIndex < modelIdRaw.length - 1) {
816
+ return {
817
+ provider: modelIdRaw.slice(0, slashIndex),
818
+ modelId: modelIdRaw.slice(slashIndex + 1)
819
+ };
820
+ }
821
+ return { provider, modelId: modelIdRaw };
822
+ }
823
+ function extractTextOutput(result) {
824
+ if (!isRecord(result)) return void 0;
825
+ const text = result["text"];
826
+ return typeof text === "string" ? text : void 0;
827
+ }
828
+ function extractObjectOutput(result) {
829
+ var _a;
830
+ if (!isRecord(result)) return void 0;
831
+ const obj = result["object"];
832
+ if (obj === void 0) return void 0;
833
+ return (_a = safeJson(obj)) != null ? _a : String(obj);
834
+ }
835
+ function isAgentClass(value) {
836
+ if (typeof value !== "function") return false;
837
+ const proto = value.prototype;
838
+ if (!isRecord(proto)) return false;
839
+ return typeof proto["generate"] === "function" && typeof proto["stream"] === "function";
840
+ }
841
+ function extractModel(result) {
842
+ if (!isRecord(result)) return void 0;
843
+ const model = result["model"];
844
+ if (typeof model === "string" && model.length) return model;
845
+ const response = result["response"];
846
+ if (isRecord(response)) {
847
+ const modelId = response["modelId"];
848
+ if (typeof modelId === "string" && modelId.length) return modelId;
849
+ }
850
+ return void 0;
851
+ }
852
+ function extractFinishReason(result) {
853
+ if (!isRecord(result)) return void 0;
854
+ if (typeof result["finishReason"] === "string") return result["finishReason"];
855
+ if (isRecord(result["finishReason"]) && typeof result["finishReason"]["unified"] === "string") {
856
+ return result["finishReason"]["unified"];
857
+ }
858
+ return void 0;
859
+ }
860
+ function bytesToBase64(bytes) {
861
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
862
+ let binary = "";
863
+ for (let i = 0; i < bytes.length; i++) {
864
+ binary += String.fromCharCode(bytes[i]);
865
+ }
866
+ if (typeof btoa === "function") return btoa(binary);
867
+ return "";
868
+ }
869
+ function asDataUrl(value, mediaType) {
870
+ if (value instanceof URL) return value.toString();
871
+ if (typeof value === "string") {
872
+ if (value.startsWith("data:")) return value;
873
+ if (value.startsWith("http://") || value.startsWith("https://")) return value;
874
+ return `data:${mediaType};base64,${value}`;
875
+ }
876
+ if (value instanceof Uint8Array) {
877
+ const base64 = bytesToBase64(value);
878
+ if (!base64) return void 0;
879
+ return `data:${mediaType};base64,${base64}`;
880
+ }
881
+ if (value instanceof ArrayBuffer) {
882
+ const base64 = bytesToBase64(new Uint8Array(value));
883
+ if (!base64) return void 0;
884
+ return `data:${mediaType};base64,${base64}`;
885
+ }
886
+ return void 0;
887
+ }
888
+ function dataPartToAttachmentValue(value) {
889
+ if (typeof value === "string") return value;
890
+ if (value instanceof URL) return value.toString();
891
+ if (value instanceof Uint8Array) return `[binary:${value.byteLength} bytes]`;
892
+ if (value instanceof ArrayBuffer) return `[binary:${value.byteLength} bytes]`;
893
+ return void 0;
894
+ }
895
+ function attachmentMediaType(part) {
896
+ if (typeof part["mediaType"] === "string") return part["mediaType"];
897
+ if (typeof part["mimeType"] === "string") return part["mimeType"];
898
+ const file = part["file"];
899
+ if (isRecord(file)) {
900
+ if (typeof file["mediaType"] === "string") return file["mediaType"];
901
+ if (typeof file["mimeType"] === "string") return file["mimeType"];
902
+ }
903
+ return void 0;
904
+ }
905
+ function attachmentName(part) {
906
+ if (typeof part["filename"] === "string") return part["filename"];
907
+ if (typeof part["name"] === "string") return part["name"];
908
+ const file = part["file"];
909
+ if (isRecord(file)) {
910
+ if (typeof file["filename"] === "string") return file["filename"];
911
+ if (typeof file["name"] === "string") return file["name"];
912
+ }
913
+ return void 0;
914
+ }
915
+ function attachmentData(part) {
916
+ if ("data" in part) return part["data"];
917
+ const file = part["file"];
918
+ if (isRecord(file)) {
919
+ if ("file_data" in file) return file["file_data"];
920
+ if ("data" in file) return file["data"];
921
+ }
922
+ return void 0;
923
+ }
924
+ function contentPartToAttachment(part, role) {
925
+ var _a, _b, _c;
926
+ const partType = part["type"];
927
+ if (typeof partType !== "string") return void 0;
928
+ if (partType === "image") {
929
+ const mediaType = (_a = attachmentMediaType(part)) != null ? _a : "image/png";
930
+ const value = asDataUrl(part["image"], mediaType);
931
+ if (!value) return void 0;
932
+ return { type: "image", role, value };
933
+ }
934
+ if (partType === "image_url") {
935
+ const imageUrlPart = part["image_url"];
936
+ const imageUrlValue = isRecord(imageUrlPart) ? imageUrlPart["url"] : imageUrlPart;
937
+ const value = asDataUrl(imageUrlValue, "image/png");
938
+ if (!value) return void 0;
939
+ return { type: "image", role, value };
940
+ }
941
+ if (partType === "file") {
942
+ const mediaType = attachmentMediaType(part);
943
+ const data = attachmentData(part);
944
+ const isImage = (mediaType == null ? void 0 : mediaType.startsWith("image/")) === true;
945
+ const value = isImage && mediaType ? asDataUrl(data, mediaType) : dataPartToAttachmentValue(data);
946
+ if (!value) return void 0;
947
+ const name = (_c = (_b = attachmentName(part)) != null ? _b : mediaType) != null ? _c : "file";
948
+ return { type: isImage ? "image" : "text", role, name, value };
949
+ }
950
+ return void 0;
951
+ }
952
+ function attachmentsFromContent(content, role) {
953
+ if (!Array.isArray(content)) return void 0;
954
+ const attachments = [];
955
+ for (const part of content) {
956
+ if (!isRecord(part)) continue;
957
+ const attachment = contentPartToAttachment(part, role);
958
+ if (attachment) attachments.push(attachment);
959
+ }
960
+ return attachments.length ? attachments : void 0;
961
+ }
962
+ function generatedFileToAttachment(file) {
963
+ var _a, _b, _c, _d;
964
+ const mediaType = typeof file["mediaType"] === "string" ? file["mediaType"] : typeof file["mimeType"] === "string" ? file["mimeType"] : void 0;
965
+ const data = (_d = (_c = (_b = (_a = file["base64Data"]) != null ? _a : file["base64"]) != null ? _b : file["uint8ArrayData"]) != null ? _c : file["uint8Array"]) != null ? _d : file["data"];
966
+ const isImage = (mediaType == null ? void 0 : mediaType.startsWith("image/")) === true;
967
+ const value = isImage && mediaType ? asDataUrl(data, mediaType) : dataPartToAttachmentValue(data);
968
+ if (!value) return void 0;
969
+ const name = typeof file["filename"] === "string" ? file["filename"] : typeof file["name"] === "string" ? file["name"] : mediaType != null ? mediaType : "file";
970
+ return {
971
+ type: isImage ? "image" : "text",
972
+ role: "output",
973
+ name,
974
+ value
975
+ };
976
+ }
977
+ async function outputAttachmentsFromFiles(files) {
978
+ let resolvedFiles = files;
979
+ if (resolvedFiles && (typeof resolvedFiles === "object" || typeof resolvedFiles === "function") && typeof resolvedFiles.then === "function") {
980
+ try {
981
+ resolvedFiles = await resolvedFiles;
982
+ } catch (e) {
983
+ return void 0;
984
+ }
985
+ }
986
+ if (!Array.isArray(resolvedFiles)) return void 0;
987
+ const attachments = [];
988
+ for (const file of resolvedFiles) {
989
+ if (!isRecord(file)) continue;
990
+ const attachment = generatedFileToAttachment(file);
991
+ if (attachment) attachments.push(attachment);
992
+ }
993
+ return attachments.length ? attachments : void 0;
994
+ }
995
+ function extractTextFromMessageContent(content) {
996
+ if (typeof content === "string") return content;
997
+ if (!Array.isArray(content)) return void 0;
998
+ let result = "";
999
+ for (const part of content) {
1000
+ if (!isRecord(part) || part["type"] !== "text" || typeof part["text"] !== "string") continue;
1001
+ result += part["text"];
1002
+ }
1003
+ return result.length ? result : void 0;
1004
+ }
1005
+ function messagesFromArgs(args) {
1006
+ const messages = args["messages"];
1007
+ if (Array.isArray(messages)) return messages;
1008
+ const prompt = args["prompt"];
1009
+ if (Array.isArray(prompt)) return prompt;
1010
+ return void 0;
1011
+ }
1012
+ function lastUserMessageFromArgs(args) {
1013
+ const messages = messagesFromArgs(args);
1014
+ if (!messages) return void 0;
1015
+ for (let i = messages.length - 1; i >= 0; i--) {
1016
+ const message = messages[i];
1017
+ if (isRecord(message) && message["role"] === "user") {
1018
+ return message;
1019
+ }
1020
+ }
1021
+ return void 0;
1022
+ }
1023
+ function extractInputAttachmentsFromArgs(args) {
1024
+ var _a;
1025
+ if (!isRecord(args)) return void 0;
1026
+ return attachmentsFromContent((_a = lastUserMessageFromArgs(args)) == null ? void 0 : _a["content"], "input");
1027
+ }
1028
+ async function extractOutputAttachmentsFromResult(result) {
1029
+ if (!isRecord(result)) return void 0;
1030
+ const fileAttachments = await outputAttachmentsFromFiles(result["files"]);
1031
+ if (fileAttachments == null ? void 0 : fileAttachments.length) return fileAttachments;
1032
+ const responseMessages = extractResponseMessages(result);
1033
+ for (let i = responseMessages.length - 1; i >= 0; i--) {
1034
+ const message = responseMessages[i];
1035
+ if (!isRecord(message) || message["role"] !== "assistant") continue;
1036
+ return attachmentsFromContent(message["content"], "output");
1037
+ }
1038
+ return attachmentsFromContent(result["content"], "output");
1039
+ }
1040
+ function lastUserMessageTextFromArgs(args) {
1041
+ var _a, _b;
1042
+ if (!isRecord(args)) return void 0;
1043
+ const content = (_a = lastUserMessageFromArgs(args)) == null ? void 0 : _a["content"];
1044
+ if (content === void 0) return void 0;
1045
+ const text = extractTextFromMessageContent(content);
1046
+ if (text !== void 0) return text;
1047
+ return (_b = safeJsonWithUint8(content)) != null ? _b : String(content);
1048
+ }
1049
+ function extractInputFromArgs(args) {
1050
+ var _a;
1051
+ if (!isRecord(args)) return void 0;
1052
+ const prompt = args["prompt"];
1053
+ if (typeof prompt === "string") return prompt;
1054
+ const messages = messagesFromArgs(args);
1055
+ if (Array.isArray(messages) && messages.length > 0) {
1056
+ const last = messages[messages.length - 1];
1057
+ if (isRecord(last)) {
1058
+ const content = last["content"];
1059
+ const text = extractTextFromMessageContent(content);
1060
+ if (text !== void 0) return text;
1061
+ const asJson = safeJson(content);
1062
+ if (asJson) return asJson;
1063
+ }
1064
+ return (_a = safeJson(messages)) != null ? _a : void 0;
1065
+ }
1066
+ const input = args["input"];
1067
+ if (typeof input === "string") return input;
1068
+ return safeJson(args);
1069
+ }
1070
+ function coerceMessagesFromArgs(args) {
1071
+ if (!isRecord(args)) return [];
1072
+ const result = [];
1073
+ if (typeof args["system"] === "string" && args["system"]) {
1074
+ result.push({ role: "system", content: args["system"] });
1075
+ }
1076
+ const messages = messagesFromArgs(args);
1077
+ if (Array.isArray(messages)) {
1078
+ for (const message of messages) {
1079
+ if (isRecord(message) && typeof message["role"] === "string") {
1080
+ result.push(message);
1081
+ }
1082
+ }
1083
+ return result;
1084
+ }
1085
+ if (typeof args["prompt"] === "string" && args["prompt"]) {
1086
+ result.push({ role: "user", content: args["prompt"] });
1087
+ }
1088
+ return result;
1089
+ }
1090
+ function extractResponseMessages(result) {
1091
+ if (!isRecord(result)) return [];
1092
+ const response = result["response"];
1093
+ if (isRecord(response) && Array.isArray(response["messages"])) {
1094
+ return response["messages"].filter(
1095
+ (message) => isRecord(message) && typeof message["role"] === "string" && "content" in message
1096
+ ).map((message) => message);
1097
+ }
1098
+ const steps = result["steps"];
1099
+ if (Array.isArray(steps) && steps.length > 0) {
1100
+ const lastStep = steps[steps.length - 1];
1101
+ if (isRecord(lastStep) && isRecord(lastStep["response"])) {
1102
+ const responseMessages = lastStep["response"]["messages"];
1103
+ if (Array.isArray(responseMessages)) {
1104
+ return responseMessages.filter(
1105
+ (message) => isRecord(message) && typeof message["role"] === "string" && "content" in message
1106
+ ).map((message) => message);
1107
+ }
1108
+ }
1109
+ }
1110
+ return [];
1111
+ }
1112
+ function buildToolCallMatchKey(info) {
1113
+ if (typeof info.toolCallId === "string" && info.toolCallId.length > 0) {
1114
+ return `id:${info.toolCallId}`;
1115
+ }
1116
+ if (typeof info.toolName === "string" && info.toolName.length > 0) {
1117
+ const inputJson = safeJsonWithUint8(info.input);
1118
+ return inputJson !== void 0 ? `name:${info.toolName}|input:${inputJson}` : `name:${info.toolName}`;
1119
+ }
1120
+ return void 0;
1121
+ }
1122
+ function isTranscriptToolResultError(part, result) {
1123
+ if (part["isError"] === true || part["type"] === "tool-error") {
1124
+ return true;
1125
+ }
1126
+ if (isRecord(result) && typeof result["type"] === "string") {
1127
+ return result["type"].startsWith("error") || result["type"] === "execution-denied";
1128
+ }
1129
+ return false;
1130
+ }
1131
+ function getTranscriptToolErrorMessage(result) {
1132
+ if (typeof result === "string" && result.length > 0) {
1133
+ return result;
1134
+ }
1135
+ if (isRecord(result)) {
1136
+ if (typeof result["value"] === "string" && result["value"].length > 0) {
1137
+ return result["value"];
1138
+ }
1139
+ if (typeof result["reason"] === "string" && result["reason"].length > 0) {
1140
+ return result["reason"];
1141
+ }
1142
+ if (typeof result["message"] === "string" && result["message"].length > 0) {
1143
+ return result["message"];
1144
+ }
1145
+ }
1146
+ return safeJsonWithUint8(result);
1147
+ }
1148
+ function getTranscriptMessageParts(message) {
1149
+ if (!isRecord(message)) return [];
1150
+ const content = message["content"];
1151
+ if (Array.isArray(content)) {
1152
+ return content.filter(isRecord);
1153
+ }
1154
+ return isRecord(content) ? [content] : [];
1155
+ }
1156
+ function getTranscriptToolCallInput(part) {
1157
+ return "input" in part ? part["input"] : "args" in part ? part["args"] : void 0;
1158
+ }
1159
+ function getTranscriptToolCallId(part) {
1160
+ const toolCallId = part["toolCallId"];
1161
+ return typeof toolCallId === "string" && toolCallId.length > 0 ? toolCallId : void 0;
1162
+ }
1163
+ function getTranscriptToolResultValue(part) {
1164
+ if ("output" in part) return part["output"];
1165
+ if ("result" in part) return part["result"];
1166
+ return part["error"];
1167
+ }
1168
+ function rememberPendingTranscriptToolCallKey(pendingKeysByToolName, toolName, key) {
1169
+ var _a;
1170
+ if (!toolName) return;
1171
+ const pendingKeys = (_a = pendingKeysByToolName.get(toolName)) != null ? _a : [];
1172
+ if (pendingKeys.includes(key)) return;
1173
+ pendingKeys.push(key);
1174
+ pendingKeysByToolName.set(toolName, pendingKeys);
1175
+ }
1176
+ function takePendingTranscriptToolCallKey(pendingKeysByToolName, toolName) {
1177
+ if (!toolName) return void 0;
1178
+ const pendingKeys = pendingKeysByToolName.get(toolName);
1179
+ if (!pendingKeys || pendingKeys.length === 0) return void 0;
1180
+ const key = pendingKeys.shift();
1181
+ if (key === void 0) return void 0;
1182
+ if (pendingKeys.length === 0) {
1183
+ pendingKeysByToolName.delete(toolName);
1184
+ }
1185
+ return key;
1186
+ }
1187
+ function mergeTranscriptToolCallPart(params) {
1188
+ var _a, _b, _c, _d;
1189
+ const { spans, pendingKeysByToolName, part } = params;
1190
+ const toolCallId = getTranscriptToolCallId(part);
1191
+ const toolName = typeof part["toolName"] === "string" ? part["toolName"] : void 0;
1192
+ const input = getTranscriptToolCallInput(part);
1193
+ const key = buildToolCallMatchKey({ toolCallId, toolName, input });
1194
+ if (!key) return;
1195
+ const placeholderKey = toolCallId == null ? buildToolCallMatchKey({ toolCallId: void 0, toolName, input: void 0 }) : void 0;
1196
+ const placeholder = placeholderKey && placeholderKey !== key ? spans.get(placeholderKey) : void 0;
1197
+ const existing = (_a = spans.get(key)) != null ? _a : placeholder;
1198
+ spans.set(key, {
1199
+ key,
1200
+ toolCallId: (_b = existing == null ? void 0 : existing.toolCallId) != null ? _b : toolCallId,
1201
+ toolName: (_c = existing == null ? void 0 : existing.toolName) != null ? _c : toolName,
1202
+ input: (_d = existing == null ? void 0 : existing.input) != null ? _d : input,
1203
+ result: existing == null ? void 0 : existing.result,
1204
+ status: existing == null ? void 0 : existing.status,
1205
+ errorMessage: existing == null ? void 0 : existing.errorMessage
1206
+ });
1207
+ if (placeholderKey && placeholderKey !== key) {
1208
+ spans.delete(placeholderKey);
1209
+ }
1210
+ if (!toolCallId && (existing == null ? void 0 : existing.result) === void 0) {
1211
+ rememberPendingTranscriptToolCallKey(pendingKeysByToolName, toolName, key);
1212
+ }
1213
+ }
1214
+ function mergeTranscriptToolResultPart(params) {
1215
+ var _a, _b, _c;
1216
+ const { spans, pendingKeysByToolName, part } = params;
1217
+ const toolCallId = getTranscriptToolCallId(part);
1218
+ const toolName = typeof part["toolName"] === "string" ? part["toolName"] : void 0;
1219
+ const result = getTranscriptToolResultValue(part);
1220
+ const fallbackKey = buildToolCallMatchKey({ toolCallId, toolName, input: void 0 });
1221
+ const key = toolCallId != null ? fallbackKey : (_a = takePendingTranscriptToolCallKey(pendingKeysByToolName, toolName)) != null ? _a : fallbackKey;
1222
+ if (!key) return;
1223
+ const existing = spans.get(key);
1224
+ const isError = isTranscriptToolResultError(part, result);
1225
+ spans.set(key, {
1226
+ key,
1227
+ toolCallId: (_b = existing == null ? void 0 : existing.toolCallId) != null ? _b : toolCallId,
1228
+ toolName: (_c = existing == null ? void 0 : existing.toolName) != null ? _c : toolName,
1229
+ input: existing == null ? void 0 : existing.input,
1230
+ result,
1231
+ status: isError ? "ERROR" : "OK",
1232
+ errorMessage: isError ? getTranscriptToolErrorMessage(result) : void 0
1233
+ });
1234
+ }
1235
+ function extractToolSpansFromMessages(messages) {
1236
+ const spans = /* @__PURE__ */ new Map();
1237
+ const pendingKeysByToolName = /* @__PURE__ */ new Map();
1238
+ for (const message of messages) {
1239
+ for (const part of getTranscriptMessageParts(message)) {
1240
+ if (part["type"] === "tool-call") {
1241
+ mergeTranscriptToolCallPart({ spans, pendingKeysByToolName, part });
1242
+ continue;
1243
+ }
1244
+ if (part["type"] === "tool-result" || part["type"] === "tool-error") {
1245
+ mergeTranscriptToolResultPart({ spans, pendingKeysByToolName, part });
1246
+ }
1247
+ }
1248
+ }
1249
+ return [...spans.values()];
1250
+ }
1251
+ function extractTextFromLmContent(content) {
1252
+ if (!Array.isArray(content)) return void 0;
1253
+ let result = "";
1254
+ for (const part of content) {
1255
+ if (isRecord(part) && part["type"] === "text" && typeof part["text"] === "string") {
1256
+ result += part["text"];
1257
+ }
1258
+ }
1259
+ return result.length ? result : void 0;
1260
+ }
1261
+ function extractToolCallsFromLmContent(content) {
1262
+ if (!Array.isArray(content)) return void 0;
1263
+ const calls = [];
1264
+ for (const part of content) {
1265
+ if (!isRecord(part) || part["type"] !== "tool-call") continue;
1266
+ const toolCallId = getTranscriptToolCallId(part);
1267
+ const toolName = typeof part["toolName"] === "string" ? part["toolName"] : void 0;
1268
+ if (toolCallId || toolName) {
1269
+ calls.push({ toolCallId, toolName, input: part["input"] });
1270
+ }
1271
+ }
1272
+ return calls.length ? calls : void 0;
1273
+ }
1274
+ function extractExperimentalTelemetry(args) {
1275
+ if (!isRecord(args)) return void 0;
1276
+ const telemetryConfig = args["experimental_telemetry"];
1277
+ if (!isRecord(telemetryConfig)) return void 0;
1278
+ return {
1279
+ functionId: typeof telemetryConfig["functionId"] === "string" ? telemetryConfig["functionId"] : void 0,
1280
+ isEnabled: typeof telemetryConfig["isEnabled"] === "boolean" ? telemetryConfig["isEnabled"] : void 0,
1281
+ recordInputs: typeof telemetryConfig["recordInputs"] === "boolean" ? telemetryConfig["recordInputs"] : void 0,
1282
+ recordOutputs: typeof telemetryConfig["recordOutputs"] === "boolean" ? telemetryConfig["recordOutputs"] : void 0,
1283
+ metadata: isRecord(telemetryConfig["metadata"]) ? telemetryConfig["metadata"] : void 0
1284
+ };
1285
+ }
1286
+ function opName(operationId, functionId) {
1287
+ return {
1288
+ operationName: `${operationId}${functionId ? ` ${functionId}` : ""}`,
1289
+ resourceName: functionId
1290
+ };
1291
+ }
1292
+ function toOtlpAttr(key, value) {
1293
+ if (value === void 0 || value === null) return void 0;
1294
+ if (typeof value === "string") return attrString(key, value);
1295
+ if (typeof value === "number")
1296
+ return Number.isInteger(value) ? attrInt(key, value) : attrDouble(key, value);
1297
+ if (typeof value === "boolean") return attrBool(key, value);
1298
+ if (Array.isArray(value) && value.every((v) => typeof v === "string"))
1299
+ return attrStringArray(key, value);
1300
+ const asJson = safeJsonWithUint8(value);
1301
+ return asJson ? attrString(key, asJson) : void 0;
1302
+ }
1303
+ function attrsFromTelemetryMetadata(metadata) {
1304
+ if (!metadata) return [];
1305
+ return Object.entries(metadata).filter(([k]) => !k.startsWith("raindrop.internal.")).map(([k, v]) => {
1306
+ const key = k === "raindrop.userId" ? "raindrop.ai.userId" : k;
1307
+ return toOtlpAttr(`ai.telemetry.metadata.${key}`, v);
1308
+ });
1309
+ }
1310
+ function attrsFromHeaders(headers) {
1311
+ if (!isRecord(headers)) return [];
1312
+ return Object.entries(headers).filter(([, v]) => typeof v === "string").map(([k, v]) => attrString(`ai.request.headers.${k}`, v));
1313
+ }
1314
+ function attrsFromSettings(args) {
1315
+ if (!isRecord(args)) return [];
1316
+ const result = [];
1317
+ const settingKeys = [
1318
+ "maxRetries",
1319
+ "timeout",
1320
+ "maxOutputTokens",
1321
+ "temperature",
1322
+ "topP",
1323
+ "topK",
1324
+ "presencePenalty",
1325
+ "frequencyPenalty",
1326
+ "seed",
1327
+ "stopSequences"
1328
+ ];
1329
+ for (const key of settingKeys) {
1330
+ if (!(key in args)) continue;
1331
+ const value = args[key];
1332
+ if (key === "stopSequences" && Array.isArray(value) && value.every((item) => typeof item === "string")) {
1333
+ result.push(attrStringArray(`ai.settings.${key}`, value));
1334
+ } else if (key === "timeout" && typeof value === "number") {
1335
+ result.push(attrInt(`ai.settings.${key}`, value));
1336
+ } else {
1337
+ result.push(toOtlpAttr(`ai.settings.${key}`, value));
1338
+ }
1339
+ }
1340
+ return result;
1341
+ }
1342
+ function attrsFromGenAiRequest(options) {
1343
+ if (!isRecord(options)) return [];
1344
+ return [
1345
+ attrDouble(
1346
+ "gen_ai.request.frequency_penalty",
1347
+ typeof options["frequencyPenalty"] === "number" ? options["frequencyPenalty"] : void 0
1348
+ ),
1349
+ attrInt(
1350
+ "gen_ai.request.max_tokens",
1351
+ typeof options["maxOutputTokens"] === "number" ? options["maxOutputTokens"] : void 0
1352
+ ),
1353
+ attrDouble(
1354
+ "gen_ai.request.presence_penalty",
1355
+ typeof options["presencePenalty"] === "number" ? options["presencePenalty"] : void 0
1356
+ ),
1357
+ ...Array.isArray(options["stopSequences"]) && options["stopSequences"].every((x) => typeof x === "string") ? [attrStringArray("gen_ai.request.stop_sequences", options["stopSequences"])] : [],
1358
+ attrDouble(
1359
+ "gen_ai.request.temperature",
1360
+ typeof options["temperature"] === "number" ? options["temperature"] : void 0
1361
+ ),
1362
+ attrInt(
1363
+ "gen_ai.request.top_k",
1364
+ typeof options["topK"] === "number" ? options["topK"] : void 0
1365
+ ),
1366
+ attrDouble(
1367
+ "gen_ai.request.top_p",
1368
+ typeof options["topP"] === "number" ? options["topP"] : void 0
1369
+ )
1370
+ ];
1371
+ }
1372
+
1373
+ // src/internal/raindrop-telemetry-integration.ts
1374
+ var RaindropTelemetryIntegration = class {
1375
+ constructor(opts) {
1376
+ this.callStates = /* @__PURE__ */ new Map();
1377
+ // ── onStart ─────────────────────────────────────────────────────────────
1378
+ this.onStart = (event) => {
1379
+ var _a, _b, _c, _d;
1380
+ if (event.isEnabled !== true) return;
1381
+ const isEmbed = event.operationId === "ai.embed" || event.operationId === "ai.embedMany";
1382
+ const recordInputs = event.recordInputs !== false;
1383
+ const recordOutputs = event.recordOutputs !== false;
1384
+ const functionId = event.functionId;
1385
+ const metadata = event.metadata;
1386
+ const callMeta = this.extractRaindropMetadata(metadata);
1387
+ const inherited = getContextManager().getParentSpanIds();
1388
+ const eventIdGenerated = (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === "true" || (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === true;
1389
+ const explicitEventId = callMeta.eventId && !eventIdGenerated ? callMeta.eventId : void 0;
1390
+ const eventId = (_d = (_c = (_b = explicitEventId != null ? explicitEventId : (_a = this.defaultContext) == null ? void 0 : _a.eventId) != null ? _b : inherited == null ? void 0 : inherited.eventId) != null ? _c : callMeta.eventId) != null ? _d : randomUUID();
1391
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
1392
+ const { operationName, resourceName } = opName(
1393
+ event.operationId,
1394
+ functionId
1395
+ );
1396
+ let rootSpan;
1397
+ if (this.sendTraces) {
1398
+ const promptAttrs = !isEmbed && recordInputs ? [
1399
+ attrString(
1400
+ "ai.prompt",
1401
+ safeJsonWithUint8({
1402
+ system: event.system,
1403
+ prompt: event.prompt,
1404
+ messages: event.messages
1405
+ })
1406
+ )
1407
+ ] : [];
1408
+ const embedAttrs = isEmbed && recordInputs ? event.operationId === "ai.embedMany" ? [
1409
+ attrString(
1410
+ "ai.values",
1411
+ safeJsonWithUint8(event.value)
1412
+ )
1413
+ ] : [attrString("ai.value", safeJsonWithUint8(event.value))] : [];
1414
+ rootSpan = this.traceShipper.startSpan({
1415
+ name: event.operationId,
1416
+ parent: inheritedParent,
1417
+ eventId,
1418
+ operationId: event.operationId,
1419
+ attributes: [
1420
+ attrString("operation.name", operationName),
1421
+ attrString("resource.name", resourceName),
1422
+ attrString("ai.telemetry.functionId", functionId),
1423
+ attrString("ai.model.provider", event.provider),
1424
+ attrString("ai.model.id", event.modelId),
1425
+ // Filter out raindrop.eventId from metadata attrs since TraceShipper
1426
+ // already sets it via the eventId arg. Without this, eventMetadata()'s
1427
+ // auto-generated ID would duplicate and override the resolved one.
1428
+ ...attrsFromTelemetryMetadata(
1429
+ metadata ? Object.fromEntries(
1430
+ Object.entries(metadata).filter(
1431
+ ([k]) => k !== "raindrop.eventId" && k !== "raindrop.internal.eventIdGenerated"
1432
+ )
1433
+ ) : void 0
1434
+ ),
1435
+ ...promptAttrs,
1436
+ ...embedAttrs
1437
+ ]
1438
+ });
1439
+ }
1440
+ this.callStates.set(event.callId, {
1441
+ operationId: event.operationId,
1442
+ eventId,
1443
+ rootSpan,
1444
+ rootParent: rootSpan ? this.spanParentRef(rootSpan) : inheritedParent,
1445
+ stepSpan: void 0,
1446
+ stepParent: void 0,
1447
+ toolSpans: /* @__PURE__ */ new Map(),
1448
+ embedSpans: /* @__PURE__ */ new Map(),
1449
+ recordInputs,
1450
+ recordOutputs,
1451
+ functionId,
1452
+ metadata,
1453
+ accumulatedText: "",
1454
+ inputText: isEmbed ? void 0 : this.extractInputText(event),
1455
+ toolCallCount: 0
1456
+ });
1457
+ };
1458
+ // ── onStepStart ─────────────────────────────────────────────────────────
1459
+ this.onStepStart = (event) => {
1460
+ const state = this.getState(event.callId);
1461
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1462
+ const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
1463
+ const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
1464
+ const { operationName, resourceName } = opName(
1465
+ stepOperationId,
1466
+ state.functionId
1467
+ );
1468
+ const inputAttrs = [];
1469
+ if (state.recordInputs) {
1470
+ if (event.promptMessages) {
1471
+ inputAttrs.push(
1472
+ attrString(
1473
+ "ai.prompt.messages",
1474
+ safeJsonWithUint8(event.promptMessages)
1475
+ )
1476
+ );
1477
+ }
1478
+ if (event.stepTools) {
1479
+ inputAttrs.push(
1480
+ attrStringArray(
1481
+ "ai.prompt.tools",
1482
+ event.stepTools.map((t) => JSON.stringify(t))
1483
+ )
1484
+ );
1485
+ }
1486
+ if (event.stepToolChoice != null) {
1487
+ inputAttrs.push(
1488
+ attrString(
1489
+ "ai.prompt.toolChoice",
1490
+ JSON.stringify(event.stepToolChoice)
1491
+ )
1492
+ );
1493
+ }
1494
+ }
1495
+ const stepSpan = this.traceShipper.startSpan({
1496
+ name: stepOperationId,
1497
+ parent: state.rootParent,
1498
+ eventId: state.eventId,
1499
+ operationId: stepOperationId,
1500
+ attributes: [
1501
+ attrString("operation.name", operationName),
1502
+ attrString("resource.name", resourceName),
1503
+ attrString("ai.telemetry.functionId", state.functionId),
1504
+ attrString("ai.model.provider", event.provider),
1505
+ attrString("ai.model.id", event.modelId),
1506
+ attrString("gen_ai.system", event.provider),
1507
+ attrString("gen_ai.request.model", event.modelId),
1508
+ ...inputAttrs
1509
+ ]
1510
+ });
1511
+ state.stepSpan = stepSpan;
1512
+ state.stepParent = this.spanParentRef(stepSpan);
1513
+ };
1514
+ // ── onToolCallStart ─────────────────────────────────────────────────────
1515
+ this.onToolCallStart = (event) => {
1516
+ const state = this.getState(event.callId);
1517
+ if (!(state == null ? void 0 : state.stepParent)) return;
1518
+ const { toolCall } = event;
1519
+ const { operationName, resourceName } = opName(
1520
+ "ai.toolCall",
1521
+ state.functionId
1522
+ );
1523
+ const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
1524
+ const toolSpan = this.traceShipper.startSpan({
1525
+ name: "ai.toolCall",
1526
+ parent: state.stepParent,
1527
+ eventId: state.eventId,
1528
+ operationId: "ai.toolCall",
1529
+ attributes: [
1530
+ attrString("operation.name", operationName),
1531
+ attrString("resource.name", resourceName),
1532
+ attrString("ai.telemetry.functionId", state.functionId),
1533
+ attrString("ai.toolCall.name", toolCall.toolName),
1534
+ attrString("ai.toolCall.id", toolCall.toolCallId),
1535
+ ...inputAttrs
1536
+ ]
1537
+ });
1538
+ state.toolSpans.set(toolCall.toolCallId, toolSpan);
1539
+ };
1540
+ // ── onToolCallFinish ────────────────────────────────────────────────────
1541
+ this.onToolCallFinish = (event) => {
1542
+ const state = this.getState(event.callId);
1543
+ if (!state) return;
1544
+ const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
1545
+ if (!toolSpan) return;
1546
+ state.toolCallCount += 1;
1547
+ if (event.success) {
1548
+ const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(event.output))] : [];
1549
+ this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
1550
+ } else {
1551
+ this.traceShipper.endSpan(toolSpan, { error: event.error });
1552
+ }
1553
+ state.toolSpans.delete(event.toolCall.toolCallId);
1554
+ };
1555
+ // ── onChunk (streaming) ─────────────────────────────────────────────────
1556
+ this.onChunk = (event) => {
1557
+ var _a, _b, _c;
1558
+ const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
1559
+ if (!callId) return;
1560
+ const state = this.getState(callId);
1561
+ if (!state) return;
1562
+ const chunk = event.chunk;
1563
+ if (!chunk || typeof chunk !== "object") return;
1564
+ if (chunk.type === "text-delta") {
1565
+ const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
1566
+ if (typeof delta === "string") {
1567
+ state.accumulatedText += delta;
1568
+ }
1569
+ }
1570
+ };
1571
+ // ── onStepFinish ────────────────────────────────────────────────────────
1572
+ this.onStepFinish = (event) => {
1573
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1574
+ const state = this.getState(event.callId);
1575
+ if (!(state == null ? void 0 : state.stepSpan)) return;
1576
+ const outputAttrs = [];
1577
+ if (state.recordOutputs) {
1578
+ outputAttrs.push(
1579
+ attrString("ai.response.finishReason", event.finishReason),
1580
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1581
+ attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
1582
+ attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
1583
+ attrString(
1584
+ "ai.response.timestamp",
1585
+ ((_d = event.response) == null ? void 0 : _d.timestamp) instanceof Date ? event.response.timestamp.toISOString() : (_e = event.response) == null ? void 0 : _e.timestamp
1586
+ ),
1587
+ attrString(
1588
+ "ai.response.providerMetadata",
1589
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1590
+ )
1591
+ );
1592
+ if (((_f = event.toolCalls) == null ? void 0 : _f.length) > 0) {
1593
+ outputAttrs.push(
1594
+ attrString(
1595
+ "ai.response.toolCalls",
1596
+ JSON.stringify(
1597
+ event.toolCalls.map((tc) => ({
1598
+ toolCallId: tc.toolCallId,
1599
+ toolName: tc.toolName,
1600
+ input: tc.input
1601
+ }))
1602
+ )
1603
+ )
1604
+ );
1605
+ }
1606
+ if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
1607
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1608
+ if (reasoningText) {
1609
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1610
+ }
1611
+ }
1612
+ }
1613
+ outputAttrs.push(
1614
+ attrStringArray("gen_ai.response.finish_reasons", [event.finishReason]),
1615
+ attrString("gen_ai.response.id", (_h = event.response) == null ? void 0 : _h.id),
1616
+ attrString("gen_ai.response.model", (_i = event.response) == null ? void 0 : _i.modelId)
1617
+ );
1618
+ const usage = event.usage;
1619
+ if (usage) {
1620
+ outputAttrs.push(
1621
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1622
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1623
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1624
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1625
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens),
1626
+ attrInt("gen_ai.usage.input_tokens", usage.inputTokens),
1627
+ attrInt("gen_ai.usage.output_tokens", usage.outputTokens)
1628
+ );
1629
+ }
1630
+ this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
1631
+ state.stepSpan = void 0;
1632
+ state.stepParent = void 0;
1633
+ };
1634
+ // ── onEmbedStart ────────────────────────────────────────────────────────
1635
+ this.onEmbedStart = (event) => {
1636
+ const state = this.getState(event.callId);
1637
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1638
+ const { operationName, resourceName } = opName(
1639
+ event.operationId,
1640
+ state.functionId
1641
+ );
1642
+ const inputAttrs = state.recordInputs ? [
1643
+ attrString(
1644
+ "ai.values",
1645
+ safeJsonWithUint8(event.values)
1646
+ )
1647
+ ] : [];
1648
+ const embedSpan = this.traceShipper.startSpan({
1649
+ name: event.operationId,
1650
+ parent: state.rootParent,
1651
+ eventId: state.eventId,
1652
+ operationId: event.operationId,
1653
+ attributes: [
1654
+ attrString("operation.name", operationName),
1655
+ attrString("resource.name", resourceName),
1656
+ attrString("ai.telemetry.functionId", state.functionId),
1657
+ ...inputAttrs
1658
+ ]
1659
+ });
1660
+ state.embedSpans.set(event.embedCallId, embedSpan);
1661
+ };
1662
+ // ── onEmbedFinish ───────────────────────────────────────────────────────
1663
+ this.onEmbedFinish = (event) => {
1664
+ var _a;
1665
+ const state = this.getState(event.callId);
1666
+ if (!state) return;
1667
+ const embedSpan = state.embedSpans.get(event.embedCallId);
1668
+ if (!embedSpan) return;
1669
+ const outputAttrs = [];
1670
+ if (state.recordOutputs) {
1671
+ outputAttrs.push(
1672
+ attrString(
1673
+ "ai.embeddings",
1674
+ safeJsonWithUint8(event.embeddings)
1675
+ )
1676
+ );
1677
+ }
1678
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1679
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1680
+ }
1681
+ this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
1682
+ state.embedSpans.delete(event.embedCallId);
1683
+ };
1684
+ // ── onFinish ────────────────────────────────────────────────────────────
1685
+ this.onFinish = (event) => {
1686
+ const state = this.getState(event.callId);
1687
+ if (!state) return;
1688
+ const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
1689
+ if (isEmbed) {
1690
+ this.finishEmbed(event, state);
1691
+ } else {
1692
+ this.finishGenerate(event, state);
1693
+ }
1694
+ this.cleanup(event.callId);
1695
+ };
1696
+ // ── onError ─────────────────────────────────────────────────────────────
1697
+ this.onError = (error) => {
1698
+ var _a;
1699
+ const event = error;
1700
+ if (!(event == null ? void 0 : event.callId)) return;
1701
+ const state = this.getState(event.callId);
1702
+ if (!state) return;
1703
+ const actualError = (_a = event.error) != null ? _a : error;
1704
+ if (state.stepSpan) {
1705
+ this.traceShipper.endSpan(state.stepSpan, { error: actualError });
1706
+ }
1707
+ for (const embedSpan of state.embedSpans.values()) {
1708
+ this.traceShipper.endSpan(embedSpan, { error: actualError });
1709
+ }
1710
+ state.embedSpans.clear();
1711
+ for (const toolSpan of state.toolSpans.values()) {
1712
+ this.traceShipper.endSpan(toolSpan, { error: actualError });
1713
+ }
1714
+ state.toolSpans.clear();
1715
+ if (state.rootSpan) {
1716
+ this.traceShipper.endSpan(state.rootSpan, { error: actualError });
1717
+ }
1718
+ this.cleanup(event.callId);
1719
+ };
1720
+ // ── executeTool ─────────────────────────────────────────────────────────
1721
+ this.executeTool = async ({
1722
+ callId,
1723
+ toolCallId,
1724
+ execute
1725
+ }) => {
1726
+ const state = this.getState(callId);
1727
+ const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
1728
+ if (!toolSpan) return execute();
1729
+ return runWithParentSpanContext(
1730
+ {
1731
+ traceIdB64: toolSpan.ids.traceIdB64,
1732
+ spanIdB64: toolSpan.ids.spanIdB64,
1733
+ eventId: state.eventId
1734
+ },
1735
+ () => execute()
1736
+ );
1737
+ };
1738
+ this.traceShipper = opts.traceShipper;
1739
+ this.eventShipper = opts.eventShipper;
1740
+ this.sendTraces = opts.sendTraces !== false;
1741
+ this.sendEvents = opts.sendEvents !== false;
1742
+ this.debug = opts.debug === true;
1743
+ this.defaultContext = opts.context;
1744
+ }
1745
+ // ── helpers ──────────────────────────────────────────────────────────────
1746
+ getState(callId) {
1747
+ return this.callStates.get(callId);
1748
+ }
1749
+ cleanup(callId) {
1750
+ this.callStates.delete(callId);
1751
+ }
1752
+ spanParentRef(span) {
1753
+ return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
1754
+ }
1755
+ extractRaindropMetadata(metadata) {
1756
+ if (!metadata) return {};
1757
+ const result = {};
1758
+ const userId = metadata["raindrop.userId"];
1759
+ if (typeof userId === "string" && userId) result.userId = userId;
1760
+ const eventId = metadata["raindrop.eventId"];
1761
+ if (typeof eventId === "string" && eventId) result.eventId = eventId;
1762
+ const convoId = metadata["raindrop.convoId"];
1763
+ if (typeof convoId === "string" && convoId) result.convoId = convoId;
1764
+ const eventName = metadata["raindrop.eventName"];
1765
+ if (typeof eventName === "string" && eventName) result.eventName = eventName;
1766
+ const properties = metadata["raindrop.properties"];
1767
+ if (typeof properties === "string") {
1768
+ try {
1769
+ result.properties = JSON.parse(properties);
1770
+ } catch (e) {
1771
+ }
1772
+ } else if (properties && typeof properties === "object") {
1773
+ result.properties = properties;
1774
+ }
1775
+ return result;
1776
+ }
1777
+ /**
1778
+ * Extract the user-facing input text from an onStart event.
1779
+ * Mirrors the logic in the v4-v6 Proxy path (lastUserMessageTextFromArgs / extractInputFromArgs).
1780
+ */
1781
+ extractInputText(event) {
1782
+ if (typeof event.prompt === "string") return event.prompt;
1783
+ if (Array.isArray(event.messages)) {
1784
+ for (let i = event.messages.length - 1; i >= 0; i--) {
1785
+ const msg = event.messages[i];
1786
+ if ((msg == null ? void 0 : msg.role) === "user") {
1787
+ if (typeof msg.content === "string") return msg.content;
1788
+ if (Array.isArray(msg.content)) {
1789
+ const textPart = msg.content.find(
1790
+ (p) => (p == null ? void 0 : p.type) === "text" && typeof p.text === "string"
1791
+ );
1792
+ if (textPart) return textPart.text;
1793
+ }
1794
+ }
1795
+ }
1796
+ }
1797
+ return void 0;
1798
+ }
1799
+ finishGenerate(event, state) {
1800
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1801
+ if (state.rootSpan) {
1802
+ const outputAttrs = [];
1803
+ if (state.recordOutputs) {
1804
+ outputAttrs.push(
1805
+ attrString("ai.response.finishReason", event.finishReason),
1806
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1807
+ attrString(
1808
+ "ai.response.providerMetadata",
1809
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1810
+ )
1811
+ );
1812
+ if (((_b = event.toolCalls) == null ? void 0 : _b.length) > 0) {
1813
+ outputAttrs.push(
1814
+ attrString(
1815
+ "ai.response.toolCalls",
1816
+ JSON.stringify(
1817
+ event.toolCalls.map((tc) => ({
1818
+ toolCallId: tc.toolCallId,
1819
+ toolName: tc.toolName,
1820
+ input: tc.input
1821
+ }))
1822
+ )
1823
+ )
1824
+ );
1825
+ }
1826
+ if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
1827
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1828
+ if (reasoningText) {
1829
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1830
+ }
1831
+ }
1832
+ }
1833
+ const usage = (_d = event.totalUsage) != null ? _d : event.usage;
1834
+ if (usage) {
1835
+ outputAttrs.push(
1836
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1837
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1838
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1839
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1840
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens)
1841
+ );
1842
+ }
1843
+ outputAttrs.push(
1844
+ attrInt("ai.toolCall.count", state.toolCallCount)
1845
+ );
1846
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1847
+ }
1848
+ if (this.sendEvents) {
1849
+ const callMeta = this.extractRaindropMetadata(state.metadata);
1850
+ const userId = (_f = callMeta.userId) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.userId;
1851
+ if (userId) {
1852
+ const eventName = (_i = (_h = callMeta.eventName) != null ? _h : (_g = this.defaultContext) == null ? void 0 : _g.eventName) != null ? _i : state.operationId;
1853
+ const output = (_j = event.text) != null ? _j : state.accumulatedText || void 0;
1854
+ const input = state.inputText;
1855
+ const model = (_k = event.response) == null ? void 0 : _k.modelId;
1856
+ const properties = {
1857
+ ...(_l = this.defaultContext) == null ? void 0 : _l.properties,
1858
+ ...callMeta.properties
1859
+ };
1860
+ const convoId = (_n = callMeta.convoId) != null ? _n : (_m = this.defaultContext) == null ? void 0 : _m.convoId;
1861
+ void this.eventShipper.patch(state.eventId, {
1862
+ eventName,
1863
+ userId,
1864
+ convoId,
1865
+ input,
1866
+ output,
1867
+ model,
1868
+ properties: Object.keys(properties).length > 0 ? properties : void 0,
1869
+ isPending: false
1870
+ }).catch((err) => {
1871
+ if (this.debug) {
1872
+ console.warn(
1873
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1874
+ );
1875
+ }
1876
+ });
1877
+ }
1878
+ }
1879
+ }
1880
+ finishEmbed(event, state) {
1881
+ var _a;
1882
+ if (!state.rootSpan) return;
1883
+ const outputAttrs = [];
1884
+ const isMany = state.operationId === "ai.embedMany";
1885
+ if (state.recordOutputs) {
1886
+ if (isMany) {
1887
+ outputAttrs.push(
1888
+ attrString("ai.embeddings", safeJsonWithUint8(event.embedding))
1889
+ );
1890
+ } else {
1891
+ outputAttrs.push(
1892
+ attrString("ai.embedding", safeJsonWithUint8(event.embedding))
1893
+ );
1894
+ }
1895
+ }
1896
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1897
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1898
+ }
1899
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1900
+ }
1901
+ };
1902
+
1903
+ // src/internal/traces.ts
1904
+ var TraceShipper2 = class extends TraceShipper {
1905
+ constructor(opts) {
1906
+ var _a, _b, _c;
1907
+ super({
1908
+ ...opts,
1909
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
1910
+ serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
1911
+ serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
1912
+ });
1913
+ }
1914
+ };
1915
+
1916
+ // src/internal/wrap/wrapAISDK.ts
1917
+ var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
1918
+ var AGENT_REPORTING_SIGNALS_DEFAULT = {
1919
+ missing_context: {
1920
+ description: "You cannot complete the task because critical information, credentials, or access is missing and the user cannot provide it. Do NOT report this for normal clarifying questions \u2014 only when you are blocked.",
1921
+ sentiment: "NEGATIVE"
1922
+ },
1923
+ repeatedly_broken_tool: {
1924
+ description: "A tool has failed or not returned the expected response on multiple distinct attempts in this conversation, preventing task completion. A single tool error is NOT enough \u2014 the tool must be persistently broken or aberrantly behaving across retries.",
1925
+ sentiment: "NEGATIVE"
1926
+ },
1927
+ capability_gap: {
1928
+ description: "The task requires a tool, permission, or capability that you do not have. For example, the user asks you to perform an action but no suitable tool exists, or you lack the necessary access. Do NOT report this if you simply need more information from the user \u2014 only when the gap is in your own capabilities.",
1929
+ sentiment: "NEGATIVE"
1930
+ },
1931
+ complete_task_failure: {
1932
+ description: "You were unable to accomplish what the user asked despite making genuine attempts. This might be things like, you genuinely do not have the capabilities the user is asking for. You have tried but run into a persistent bug in the environment etc. This is NOT a refusal or policy block \u2014 you tried and failed to deliver the result.",
1933
+ sentiment: "NEGATIVE"
1934
+ }
1935
+ };
1936
+ var AGENT_REPORTING_TOOL_PREAMBLE = "You have a diagnostic tool for flagging serious failures for developer review. Only call this when you hit a significant, unrecoverable problem \u2014 not for minor hiccups or routine clarifications. If you can still help the user, do that instead of calling this tool. This tool is invisible to the user \u2014 never mention it or its output.";
1937
+ var pendingStoresByShipper = /* @__PURE__ */ new WeakMap();
1938
+ var PendingToolSpanStore = class _PendingToolSpanStore {
1939
+ constructor() {
1940
+ this.spans = /* @__PURE__ */ new Map();
1941
+ }
1942
+ static for(traceShipper, eventId) {
1943
+ let byEvent = pendingStoresByShipper.get(traceShipper);
1944
+ if (!byEvent) {
1945
+ byEvent = /* @__PURE__ */ new Map();
1946
+ pendingStoresByShipper.set(traceShipper, byEvent);
1947
+ }
1948
+ let store = byEvent.get(eventId);
1949
+ if (!store) {
1950
+ store = new _PendingToolSpanStore();
1951
+ byEvent.set(eventId, store);
1952
+ }
1953
+ return store;
1954
+ }
1955
+ resolve(resolvedToolSpans, ctx) {
1956
+ for (const [key, span] of this.spans) {
1957
+ const toolCall = resolvedToolSpans.get(key);
1958
+ if (!toolCall) continue;
1959
+ finishToolSpan(toolCall, span, ctx, span.startTimeUnixNano);
1960
+ this.spans.delete(key);
1961
+ }
1962
+ }
1963
+ remember(toolCall, rootSpan, ctx, startTimeUnixNano) {
1964
+ if (this.spans.has(toolCall.key)) return;
1965
+ this.spans.set(toolCall.key, startToolSpan(toolCall, rootSpan, ctx, startTimeUnixNano));
1966
+ }
1967
+ closeAll(traceShipper) {
1968
+ for (const [, span] of this.spans) {
1969
+ traceShipper.endSpan(span, { endTimeUnixNano: span.startTimeUnixNano });
1970
+ }
1971
+ this.spans.clear();
1972
+ }
1973
+ cleanup(traceShipper, eventId) {
1974
+ if (this.spans.size > 0) return;
1975
+ const byEvent = pendingStoresByShipper.get(traceShipper);
1976
+ if (!byEvent) return;
1977
+ byEvent.delete(eventId);
1978
+ if (byEvent.size === 0) pendingStoresByShipper.delete(traceShipper);
1979
+ }
1980
+ };
1981
+ var warnedMissingUserId = false;
1982
+ function warnMissingUserIdOnce() {
1983
+ if (warnedMissingUserId) return;
1984
+ warnedMissingUserId = true;
1985
+ console.warn(
1986
+ "[raindrop-ai/ai-sdk] userId was not provided in wrap() context or via eventMetadata(). Events will be skipped unless a userId is provided."
1987
+ );
1988
+ }
1989
+ function _resetWarnedMissingUserId() {
1990
+ warnedMissingUserId = false;
1991
+ }
1992
+ function extractRaindropCallOptions(options) {
1993
+ if (!isRecord(options)) return {};
1994
+ const em = options["metadata"];
1995
+ if (isRecord(em)) return extractRaindropMetadata(em);
1996
+ const telemetry = extractExperimentalTelemetry(options);
1997
+ if (telemetry == null ? void 0 : telemetry.metadata) return extractRaindropMetadata(telemetry.metadata);
1998
+ return {};
1999
+ }
2000
+ function extractRaindropMetadata(metadata) {
2001
+ if (!metadata || typeof metadata !== "object") return {};
2002
+ const result = {};
2003
+ const userId = metadata["raindrop.userId"];
2004
+ if (typeof userId === "string" && userId) result.userId = userId;
2005
+ const eventId = metadata["raindrop.eventId"];
2006
+ if (typeof eventId === "string" && eventId) result.eventId = eventId;
2007
+ const eventIdGenerated = metadata["raindrop.internal.eventIdGenerated"];
2008
+ if (eventIdGenerated === true || eventIdGenerated === "true" || eventIdGenerated === "1") {
2009
+ result.eventIdGenerated = true;
2010
+ }
2011
+ const convoId = metadata["raindrop.convoId"];
2012
+ if (typeof convoId === "string" && convoId) result.convoId = convoId;
2013
+ const eventName = metadata["raindrop.eventName"];
2014
+ if (typeof eventName === "string" && eventName) result.eventName = eventName;
2015
+ const properties = metadata["raindrop.properties"];
2016
+ if (typeof properties === "string") {
2017
+ try {
2018
+ result.properties = JSON.parse(properties);
2019
+ } catch (e) {
2020
+ }
2021
+ } else if (properties && typeof properties === "object") {
2022
+ result.properties = properties;
2023
+ }
2024
+ return result;
2025
+ }
2026
+ function mergeContexts(wrapTime, callTime) {
2027
+ const result = { ...wrapTime };
2028
+ if (callTime.userId) result.userId = callTime.userId;
2029
+ if (callTime.eventId) result.eventId = callTime.eventId;
2030
+ if (callTime.convoId) result.convoId = callTime.convoId;
2031
+ if (callTime.eventName) result.eventName = callTime.eventName;
2032
+ if (callTime.properties) {
2033
+ result.properties = {
2034
+ ...wrapTime.properties,
2035
+ ...callTime.properties
2036
+ };
2037
+ }
2038
+ return result;
2039
+ }
2040
+ function normalizeSelfDiagnosticsSignals(signals) {
2041
+ if (!signals) return AGENT_REPORTING_SIGNALS_DEFAULT;
2042
+ const normalizedEntries = Object.entries(signals).map(([key, value]) => {
2043
+ var _a;
2044
+ const signalKey = key.trim();
2045
+ if (!signalKey || !value || typeof value !== "object") return void 0;
2046
+ const description = (_a = value.description) == null ? void 0 : _a.trim();
2047
+ if (!description) return void 0;
2048
+ const sentiment = value.sentiment;
2049
+ return [
2050
+ signalKey,
2051
+ {
2052
+ description,
2053
+ ...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
2054
+ }
2055
+ ];
2056
+ }).filter(
2057
+ (entry) => entry !== void 0
2058
+ );
2059
+ if (normalizedEntries.length === 0) return AGENT_REPORTING_SIGNALS_DEFAULT;
2060
+ return Object.fromEntries(normalizedEntries);
2061
+ }
2062
+ function normalizeSelfDiagnosticsConfig(options) {
2063
+ var _a, _b;
2064
+ if (!(options == null ? void 0 : options.enabled)) return void 0;
2065
+ const signalDefinitions = normalizeSelfDiagnosticsSignals(options.signals);
2066
+ const signalKeys = Object.keys(signalDefinitions);
2067
+ const signalDescriptions = {};
2068
+ const signalSentiments = {};
2069
+ for (const signalKey of signalKeys) {
2070
+ const def = signalDefinitions[signalKey];
2071
+ if (!def) continue;
2072
+ signalDescriptions[signalKey] = def.description;
2073
+ signalSentiments[signalKey] = def.sentiment;
2074
+ }
2075
+ const customGuidanceText = ((_a = options.guidance) == null ? void 0 : _a.trim()) || "";
2076
+ const toolName = ((_b = options.toolName) == null ? void 0 : _b.trim()) || AGENT_REPORTING_TOOL_NAME_DEFAULT;
2077
+ const signalList = signalKeys.map((signalKey) => {
2078
+ const sentiment = signalSentiments[signalKey];
2079
+ const sentimentTag = sentiment ? ` [${sentiment.toLowerCase()}]` : "";
2080
+ return `- ${signalKey}: ${signalDescriptions[signalKey]}${sentimentTag}`;
2081
+ }).join("\n");
2082
+ const guidanceBlock = customGuidanceText ? `
2083
+ Additional guidance: ${customGuidanceText}
2084
+ ` : "";
2085
+ const toolDescription = `${AGENT_REPORTING_TOOL_PREAMBLE}
2086
+
2087
+ When to call:
2088
+ - You are blocked from completing the task due to missing information or access that the user cannot provide.
2089
+ - A tool is persistently failing across multiple attempts, not just a single transient error.
2090
+ - The task requires a tool, permission, or capability you do not have.
2091
+ - You genuinely cannot deliver what the user asked for despite trying.
2092
+
2093
+ When NOT to call:
2094
+ - Normal clarifying questions or back-and-forth with the user.
2095
+ - A single tool error that you can recover from or retry.
2096
+ - You successfully completed the task, even if it was difficult.
2097
+ - Policy refusals or content filtering \u2014 those are working as intended.
2098
+
2099
+ Rules:
2100
+ 1. Pick the single best category.
2101
+ 2. Do not fabricate issues. Only report what is evident from the conversation.
2102
+ 3. Err on the side of NOT calling this tool. When in doubt, help the user instead.
2103
+ ${guidanceBlock}
2104
+ Categories:
2105
+ ${signalList}`;
2106
+ return {
2107
+ toolName,
2108
+ toolDescription,
2109
+ signalKeys,
2110
+ signalKeySet: new Set(signalKeys),
2111
+ signalDescriptions,
2112
+ signalSentiments
2113
+ };
2114
+ }
2115
+ function resolveJsonSchemaFactory(aiSDK) {
2116
+ if (!isRecord(aiSDK) || !isFunction(aiSDK["jsonSchema"])) return void 0;
2117
+ return aiSDK["jsonSchema"];
2118
+ }
2119
+ function detectAISDKVersion(aiSDK) {
2120
+ if (!isRecord(aiSDK)) return "unknown";
2121
+ if (isFunction(aiSDK["jsonSchema"])) return "6";
2122
+ if (isFunction(aiSDK["tool"])) return "5";
2123
+ return "4";
2124
+ }
2125
+ function hasStructuredTelemetryEvents(aiSDK) {
2126
+ return isRecord(aiSDK) && isFunction(aiSDK["registerTelemetryIntegration"]) && isFunction(aiSDK["experimental_streamModelCall"]);
2127
+ }
2128
+ function asVercelSchema(jsonSchemaObj) {
2129
+ const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
2130
+ const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
2131
+ return {
2132
+ [schemaSymbol]: true,
2133
+ [validatorSymbol]: true,
2134
+ _type: void 0,
2135
+ jsonSchema: jsonSchemaObj,
2136
+ validate: (value) => ({ success: true, value })
2137
+ };
2138
+ }
2139
+ function createSelfDiagnosticsTool(ctx) {
2140
+ const config = ctx.selfDiagnostics;
2141
+ if (!config) return void 0;
2142
+ const schema = {
2143
+ type: "object",
2144
+ additionalProperties: false,
2145
+ properties: {
2146
+ category: {
2147
+ type: "string",
2148
+ enum: config.signalKeys,
2149
+ description: "The single best-matching category from the list above."
2150
+ },
2151
+ detail: {
2152
+ type: "string",
2153
+ description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
2154
+ }
2155
+ },
2156
+ required: ["category", "detail"]
2157
+ };
2158
+ const parameters = asVercelSchema(schema);
2159
+ let inputSchema = parameters;
2160
+ if (ctx.jsonSchemaFactory) {
2161
+ try {
2162
+ inputSchema = ctx.jsonSchemaFactory(schema);
2163
+ } catch (e) {
2164
+ inputSchema = parameters;
2165
+ }
2166
+ }
2167
+ const execute = async (rawInput) => {
2168
+ var _a;
2169
+ const input = isRecord(rawInput) ? rawInput : void 0;
2170
+ const fallbackCategory = (_a = config.signalKeys[0]) != null ? _a : "unknown";
2171
+ const categoryCandidate = typeof (input == null ? void 0 : input["category"]) === "string" ? input["category"].trim() : void 0;
2172
+ const category = categoryCandidate && config.signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
2173
+ const detail = typeof (input == null ? void 0 : input["detail"]) === "string" ? input["detail"].trim() : "";
2174
+ const signalDescription = config.signalDescriptions[category];
2175
+ const signalSentiment = config.signalSentiments[category];
2176
+ void ctx.eventShipper.trackSignal({
2177
+ eventId: ctx.eventId,
2178
+ name: `self diagnostics - ${category}`,
2179
+ type: "agent",
2180
+ sentiment: signalSentiment,
2181
+ properties: {
2182
+ source: "agent_reporting_tool",
2183
+ category,
2184
+ signal_description: signalDescription,
2185
+ ai_sdk_version: ctx.aiSDKVersion,
2186
+ ...detail ? { detail } : {}
2187
+ }
2188
+ }).catch((err) => {
2189
+ if (ctx.debug) {
2190
+ const msg = err instanceof Error ? err.message : String(err);
2191
+ console.warn(`[raindrop-ai/ai-sdk] selfDiagnostics signal dispatch failed: ${msg}`);
2192
+ }
2193
+ });
2194
+ return { acknowledged: true, category };
2195
+ };
2196
+ return {
2197
+ description: config.toolDescription,
2198
+ execute,
2199
+ parameters,
2200
+ inputSchema
2201
+ };
2202
+ }
2203
+ function getCurrentParentSpanContextSync() {
2204
+ return getContextManager().getParentSpanIds();
2205
+ }
2206
+ function runWithParentSpanContextSync(ctx, fn) {
2207
+ const cm = getContextManager();
2208
+ const span = {
2209
+ traceIdB64: ctx.traceIdB64,
2210
+ spanIdB64: ctx.spanIdB64,
2211
+ eventId: ctx.eventId
2212
+ };
2213
+ return cm.runInContext(span, fn);
2214
+ }
2215
+ function isAsyncIterable(value) {
2216
+ return value !== null && typeof value === "object" && Symbol.asyncIterator in value;
2217
+ }
2218
+ function firstFiniteNumber(...values) {
2219
+ for (const value of values) {
2220
+ if (typeof value === "number" && Number.isFinite(value)) {
2221
+ return value;
2222
+ }
2223
+ }
2224
+ return void 0;
2225
+ }
2226
+ function resolveUsageRecord(result) {
2227
+ if (!isRecord(result)) return void 0;
2228
+ let usage;
2229
+ try {
2230
+ if (isRecord(result["totalUsage"])) {
2231
+ usage = result["totalUsage"];
2232
+ } else if (isRecord(result["usage"])) {
2233
+ usage = result["usage"];
2234
+ }
2235
+ } catch (e) {
2236
+ return void 0;
2237
+ }
2238
+ return isRecord(usage) ? usage : void 0;
2239
+ }
2240
+ function extractUsageMetrics(result) {
2241
+ const usage = resolveUsageRecord(result);
2242
+ if (!usage) return {};
2243
+ const inputTokenValue = usage["inputTokens"];
2244
+ const outputTokenValue = usage["outputTokens"];
2245
+ const inputTokens = firstFiniteNumber(
2246
+ isRecord(inputTokenValue) ? inputTokenValue["total"] : void 0,
2247
+ inputTokenValue,
2248
+ usage["promptTokens"],
2249
+ usage["prompt_tokens"]
2250
+ );
2251
+ const outputTokens = firstFiniteNumber(
2252
+ isRecord(outputTokenValue) ? outputTokenValue["total"] : void 0,
2253
+ outputTokenValue,
2254
+ usage["completionTokens"],
2255
+ usage["completion_tokens"]
2256
+ );
2257
+ const totalTokens = firstFiniteNumber(
2258
+ usage["totalTokens"],
2259
+ usage["tokens"],
2260
+ usage["total_tokens"],
2261
+ inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0
2262
+ );
2263
+ const reasoningTokens = firstFiniteNumber(
2264
+ isRecord(outputTokenValue) ? outputTokenValue["reasoning"] : void 0,
2265
+ usage["reasoningTokens"],
2266
+ usage["completionReasoningTokens"],
2267
+ usage["completion_reasoning_tokens"],
2268
+ usage["reasoning_tokens"],
2269
+ usage["thinkingTokens"],
2270
+ usage["thinking_tokens"]
2271
+ );
2272
+ const cachedInputTokens = firstFiniteNumber(
2273
+ isRecord(inputTokenValue) ? inputTokenValue["cacheRead"] : void 0,
2274
+ usage["cachedInputTokens"],
2275
+ usage["promptCachedTokens"],
2276
+ usage["prompt_cached_tokens"]
2277
+ );
2278
+ return {
2279
+ inputTokens,
2280
+ outputTokens,
2281
+ totalTokens,
2282
+ reasoningTokens,
2283
+ cachedInputTokens
2284
+ };
2285
+ }
2286
+ function isObjectOperation(operation) {
2287
+ return operation === "generateObject" || operation === "streamObject";
2288
+ }
2289
+ function logFinalizeError(debug, err) {
2290
+ if (debug) {
2291
+ console.warn(
2292
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
2293
+ );
2294
+ }
2295
+ }
2296
+ function shouldKeepEventPending(params) {
2297
+ if (params.error != null || !params.canKeepEventPending) return false;
2298
+ return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
2299
+ }
2300
+ async function safeFinalize(finalize, debug, result, error) {
2301
+ try {
2302
+ await finalize(result, error);
2303
+ } catch (finalizeErr) {
2304
+ logFinalizeError(debug, finalizeErr);
2305
+ }
2306
+ }
2307
+ function runWithRootContextSync(rootSpan, eventId, fn) {
2308
+ if (!rootSpan) return fn();
2309
+ return runWithParentSpanContextSync(
2310
+ { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64, eventId },
2311
+ fn
2312
+ );
2313
+ }
2314
+ async function runWithRootContextAsync(rootSpan, eventId, fn) {
2315
+ if (!rootSpan) return await fn();
2316
+ return await runWithParentSpanContext(
2317
+ { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64, eventId },
2318
+ fn
2319
+ );
2320
+ }
2321
+ function teeStreamObjectBaseStream(result) {
2322
+ if (!result || !isRecord(result)) return;
2323
+ const baseStream = result["baseStream"];
2324
+ if (!(baseStream && typeof baseStream === "object" && "tee" in baseStream)) return;
2325
+ try {
2326
+ const [consumeStream, userStream] = baseStream.tee();
2327
+ result["baseStream"] = userStream;
2328
+ consumeStream.pipeTo(new WritableStream({ write() {
2329
+ } })).catch(() => {
2330
+ });
2331
+ } catch (e) {
2332
+ }
2333
+ }
2334
+ function setupOperation(params) {
2335
+ var _a, _b, _c;
2336
+ const {
2337
+ operation,
2338
+ arg,
2339
+ inherited,
2340
+ aiSDK,
2341
+ options,
2342
+ eventShipper,
2343
+ traceShipper,
2344
+ debug,
2345
+ selfDiagnostics,
2346
+ sendTraces
2347
+ } = params;
2348
+ const wrapTimeCtx = resolveContext(options.context, { operation, args: arg });
2349
+ const telemetry = extractExperimentalTelemetry(arg);
2350
+ const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
2351
+ const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
2352
+ if (!mergedCtx.userId) warnMissingUserIdOnce();
2353
+ const hasCallTimeEventId = callTimeCtx.eventId != null;
2354
+ const hasWrapTimeEventId = wrapTimeCtx.eventId != null;
2355
+ const eventId = (_c = (_b = (_a = callTimeCtx.eventId) != null ? _a : wrapTimeCtx.eventId) != null ? _b : inherited == null ? void 0 : inherited.eventId) != null ? _c : randomUUID();
2356
+ const ctx = { ...mergedCtx, eventId };
2357
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
2358
+ const outerOperationId = `ai.${operation}`;
2359
+ const { operationName, resourceName } = opName(outerOperationId, telemetry == null ? void 0 : telemetry.functionId);
2360
+ const modelInfoFromArgs = isRecord(arg) ? extractModelInfo(arg["model"]) : {};
2361
+ const rootSpan = sendTraces ? traceShipper.startSpan({
2362
+ name: outerOperationId,
2363
+ parent: inheritedParent,
2364
+ eventId,
2365
+ operationId: outerOperationId,
2366
+ attributes: [
2367
+ attrString("operation.name", operationName),
2368
+ attrString("resource.name", resourceName),
2369
+ attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
2370
+ attrString("ai.model.provider", modelInfoFromArgs.provider),
2371
+ attrString("ai.model.id", modelInfoFromArgs.modelId),
2372
+ ...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
2373
+ ...attrsFromHeaders(isRecord(arg) ? arg["headers"] : void 0),
2374
+ ...attrsFromSettings(arg),
2375
+ ...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
2376
+ attrString(
2377
+ "ai.prompt",
2378
+ safeJsonWithUint8({
2379
+ system: isRecord(arg) ? arg["system"] : void 0,
2380
+ prompt: isRecord(arg) ? arg["prompt"] : void 0,
2381
+ messages: isRecord(arg) ? arg["messages"] : void 0
2382
+ })
2383
+ )
2384
+ ]
2385
+ ]
2386
+ }) : void 0;
2387
+ const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
2388
+ const operationSelfDiagnostics = isObjectOperation(operation) ? void 0 : selfDiagnostics;
2389
+ const wrapCtx = {
2390
+ eventId,
2391
+ telemetry,
2392
+ sendTraces,
2393
+ debug,
2394
+ eventShipper,
2395
+ traceShipper,
2396
+ rootParentForChildren,
2397
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2398
+ selfDiagnostics: operationSelfDiagnostics,
2399
+ aiSDKVersion: detectAISDKVersion(aiSDK)
2400
+ };
2401
+ const toolCalls = [];
2402
+ const argsWithWrappedTools = wrapTools(arg, wrapCtx, toolCalls);
2403
+ const wrappedArgs = wrapModel(argsWithWrappedTools, aiSDK, outerOperationId, wrapCtx);
2404
+ return {
2405
+ eventId,
2406
+ ctx,
2407
+ canKeepEventPending: hasCallTimeEventId ? callTimeCtx.eventIdGenerated !== true : hasWrapTimeEventId,
2408
+ telemetry,
2409
+ rootSpan,
2410
+ wrappedArgs,
2411
+ toolCalls
2412
+ };
2413
+ }
2414
+ function createFinalize(params) {
2415
+ const {
2416
+ operation,
2417
+ arg,
2418
+ setup,
2419
+ autoAttachmentEnabled,
2420
+ sendEvents,
2421
+ debug,
2422
+ options,
2423
+ eventShipper,
2424
+ traceShipper
2425
+ } = params;
2426
+ return async (result, error) => {
2427
+ var _a, _b, _c, _d;
2428
+ const usage = extractUsageMetrics(result);
2429
+ const model = extractModel(result);
2430
+ const finishReason = extractFinishReason(result);
2431
+ const keepEventPending = shouldKeepEventPending({
2432
+ finishReason,
2433
+ error,
2434
+ canKeepEventPending: setup.canKeepEventPending
2435
+ });
2436
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(arg) : void 0;
2437
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
2438
+ const baseMessages = coerceMessagesFromArgs(arg);
2439
+ const responseMessages = extractResponseMessages(result);
2440
+ const allMessages = [...baseMessages, ...responseMessages];
2441
+ const outputText = extractTextOutput(result);
2442
+ const outputObjectJson = extractObjectOutput(result);
2443
+ const defaultOutput = isObjectOperation(operation) ? outputObjectJson : outputText;
2444
+ const defaultPatch = {
2445
+ eventName: (_a = setup.ctx.eventName) != null ? _a : operation,
2446
+ input: (_b = lastUserMessageTextFromArgs(arg)) != null ? _b : extractInputFromArgs(arg),
2447
+ output: defaultOutput,
2448
+ model,
2449
+ properties: setup.ctx.properties,
2450
+ attachments: mergeAttachments(setup.ctx.attachments, inputAttachments, outputAttachments)
2451
+ };
2452
+ const built = await maybeBuildEvent(options.buildEvent, allMessages);
2453
+ const patch = mergeBuildEventPatch(defaultPatch, built);
2454
+ const output = patch.output;
2455
+ const finalModel = (_c = patch.model) != null ? _c : model;
2456
+ if (setup.rootSpan) {
2457
+ const spanEndTimeUnixNano = nowUnixNanoString();
2458
+ const syntheticToolCallCount = emitTranscriptToolCallSpans({
2459
+ baseMessages,
2460
+ responseMessages,
2461
+ rootSpan: setup.rootSpan,
2462
+ eventId: setup.eventId,
2463
+ telemetry: setup.telemetry,
2464
+ toolCalls: setup.toolCalls,
2465
+ traceShipper,
2466
+ endTimeUnixNano: spanEndTimeUnixNano,
2467
+ keepEventPending
2468
+ });
2469
+ const providerMetadata = isRecord(result) ? result["providerMetadata"] : void 0;
2470
+ const resultToolCalls = isRecord(result) && Array.isArray(result["toolCalls"]) ? safeJsonWithUint8(result["toolCalls"]) : setup.toolCalls.length ? safeJsonWithUint8(setup.toolCalls) : void 0;
2471
+ traceShipper.endSpan(setup.rootSpan, {
2472
+ attributes: [
2473
+ ...((_d = setup.telemetry) == null ? void 0 : _d.recordOutputs) === false ? [] : [
2474
+ attrString("ai.response.finishReason", finishReason),
2475
+ isObjectOperation(operation) ? attrString("ai.response.object", output) : attrString("ai.response.text", output),
2476
+ attrString("ai.response.toolCalls", resultToolCalls),
2477
+ attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
2478
+ ],
2479
+ attrInt("ai.usage.promptTokens", usage == null ? void 0 : usage.inputTokens),
2480
+ attrInt("ai.usage.completionTokens", usage == null ? void 0 : usage.outputTokens),
2481
+ attrInt("ai.usage.inputTokens", usage == null ? void 0 : usage.inputTokens),
2482
+ attrInt("ai.usage.outputTokens", usage == null ? void 0 : usage.outputTokens),
2483
+ attrInt("ai.usage.totalTokens", usage == null ? void 0 : usage.totalTokens),
2484
+ attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
2485
+ attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
2486
+ attrInt("ai.toolCall.count", setup.toolCalls.length + syntheticToolCallCount),
2487
+ ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
2488
+ ],
2489
+ error,
2490
+ endTimeUnixNano: spanEndTimeUnixNano
2491
+ });
2492
+ }
2493
+ if (sendEvents) {
2494
+ void eventShipper.patch(setup.eventId, {
2495
+ eventName: patch.eventName,
2496
+ userId: setup.ctx.userId,
2497
+ convoId: setup.ctx.convoId,
2498
+ input: patch.input,
2499
+ output,
2500
+ model: finalModel,
2501
+ properties: patch.properties,
2502
+ attachments: patch.attachments,
2503
+ isPending: keepEventPending
2504
+ }).catch((err) => {
2505
+ if (debug) {
2506
+ console.warn(
2507
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
2508
+ );
2509
+ }
2510
+ });
2511
+ }
2512
+ };
2513
+ }
2514
+ function hasToolResult(toolCall) {
2515
+ return toolCall.result !== void 0 || toolCall.status === "ERROR";
2516
+ }
2517
+ function getExecutedToolCallKeys(toolCalls) {
2518
+ return new Set(
2519
+ toolCalls.map((tc) => buildToolCallMatchKey({ toolCallId: tc.id, toolName: tc.name, input: tc.args })).filter((key) => typeof key === "string" && key.length > 0)
2520
+ );
2521
+ }
2522
+ function getResolvedToolSpans(messages, executedKeys) {
2523
+ return new Map(
2524
+ extractToolSpansFromMessages(messages).filter((tc) => hasToolResult(tc) && !executedKeys.has(tc.key)).map((tc) => [tc.key, tc])
2525
+ );
2526
+ }
2527
+ function startToolSpan(toolCall, rootSpan, ctx, startTimeUnixNano) {
2528
+ var _a, _b, _c;
2529
+ const { operationName, resourceName } = opName("ai.toolCall", (_a = ctx.telemetry) == null ? void 0 : _a.functionId);
2530
+ return ctx.traceShipper.startSpan({
2531
+ name: "ai.toolCall",
2532
+ parent: { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 },
2533
+ eventId: ctx.eventId,
2534
+ operationId: "ai.toolCall",
2535
+ attributes: [
2536
+ attrString("operation.name", operationName),
2537
+ attrString("resource.name", resourceName),
2538
+ attrString("ai.telemetry.functionId", (_b = ctx.telemetry) == null ? void 0 : _b.functionId),
2539
+ attrString("ai.toolCall.name", toolCall.toolName),
2540
+ attrString("ai.toolCall.id", toolCall.toolCallId),
2541
+ ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))]
2542
+ ],
2543
+ startTimeUnixNano
2544
+ });
2545
+ }
2546
+ function finishToolSpan(toolCall, span, ctx, endTimeUnixNano) {
2547
+ var _a, _b, _c;
2548
+ const endAttributes = toolCall.status === "ERROR" ? [attrString("error.message", (_a = toolCall.errorMessage) != null ? _a : "Tool call failed")] : ((_b = ctx.telemetry) == null ? void 0 : _b.recordOutputs) === false ? [] : [attrString("ai.toolCall.result", safeJsonWithUint8(toolCall.result))];
2549
+ ctx.traceShipper.endSpan(span, {
2550
+ attributes: endAttributes,
2551
+ ...toolCall.status === "ERROR" ? { error: new Error((_c = toolCall.errorMessage) != null ? _c : "Tool call failed") } : {},
2552
+ endTimeUnixNano
2553
+ });
2554
+ }
2555
+ function emitToolSpan(toolCall, rootSpan, ctx, timeUnixNano) {
2556
+ const span = startToolSpan(toolCall, rootSpan, ctx, timeUnixNano);
2557
+ finishToolSpan(toolCall, span, ctx, timeUnixNano);
2558
+ }
2559
+ function emitTranscriptToolCallSpans(params) {
2560
+ const store = PendingToolSpanStore.for(params.traceShipper, params.eventId);
2561
+ const responseToolSpans = extractToolSpansFromMessages(params.responseMessages);
2562
+ if (responseToolSpans.length === 0 && params.baseMessages.length === 0) {
2563
+ if (!params.keepEventPending) {
2564
+ store.closeAll(params.traceShipper);
2565
+ }
2566
+ store.cleanup(params.traceShipper, params.eventId);
2567
+ return 0;
2568
+ }
2569
+ const ctx = {
2570
+ eventId: params.eventId,
2571
+ telemetry: params.telemetry,
2572
+ traceShipper: params.traceShipper
2573
+ };
2574
+ const executedKeys = getExecutedToolCallKeys(params.toolCalls);
2575
+ const resolvedSpans = getResolvedToolSpans(
2576
+ [...params.baseMessages, ...params.responseMessages],
2577
+ executedKeys
2578
+ );
2579
+ store.resolve(resolvedSpans, ctx);
2580
+ let syntheticToolCallCount = 0;
2581
+ for (const toolCall of responseToolSpans) {
2582
+ if (executedKeys.has(toolCall.key)) continue;
2583
+ executedKeys.add(toolCall.key);
2584
+ syntheticToolCallCount += 1;
2585
+ if (hasToolResult(toolCall) || !params.keepEventPending) {
2586
+ emitToolSpan(toolCall, params.rootSpan, ctx, params.endTimeUnixNano);
2587
+ } else {
2588
+ store.remember(toolCall, params.rootSpan, ctx, params.endTimeUnixNano);
2589
+ }
2590
+ }
2591
+ if (!params.keepEventPending) {
2592
+ store.closeAll(params.traceShipper);
2593
+ }
2594
+ store.cleanup(params.traceShipper, params.eventId);
2595
+ return syntheticToolCallCount;
2596
+ }
2597
+ function executeStreamingOperation(params) {
2598
+ const {
2599
+ operation,
2600
+ arg,
2601
+ callArgs,
2602
+ aiSDK,
2603
+ original,
2604
+ deps,
2605
+ sendEvents,
2606
+ sendTraces,
2607
+ selfDiagnostics,
2608
+ autoAttachmentEnabled,
2609
+ debug
2610
+ } = params;
2611
+ const setup = setupOperation({
2612
+ operation,
2613
+ arg,
2614
+ inherited: getCurrentParentSpanContextSync(),
2615
+ aiSDK,
2616
+ options: deps.options,
2617
+ eventShipper: deps.eventShipper,
2618
+ traceShipper: deps.traceShipper,
2619
+ debug,
2620
+ selfDiagnostics,
2621
+ sendTraces
2622
+ });
2623
+ const finalize = createFinalize({
2624
+ operation,
2625
+ arg,
2626
+ setup,
2627
+ autoAttachmentEnabled,
2628
+ sendEvents,
2629
+ debug,
2630
+ options: deps.options,
2631
+ eventShipper: deps.eventShipper,
2632
+ traceShipper: deps.traceShipper
2633
+ });
2634
+ const argWithOnFinish = wrapOnFinish(setup.wrappedArgs, async (result) => {
2635
+ await safeFinalize(finalize, debug, result);
2636
+ });
2637
+ const callOriginal = (...args) => {
2638
+ return original.call(aiSDK, ...args);
2639
+ };
2640
+ try {
2641
+ const result = runWithRootContextSync(setup.rootSpan, setup.eventId, () => {
2642
+ const nextArgs = [...callArgs];
2643
+ nextArgs[0] = argWithOnFinish;
2644
+ return callOriginal(...nextArgs);
2645
+ });
2646
+ if (operation === "streamObject") {
2647
+ teeStreamObjectBaseStream(result);
2648
+ }
2649
+ return result;
2650
+ } catch (error) {
2651
+ void safeFinalize(finalize, debug, void 0, error);
2652
+ throw error;
2653
+ }
2654
+ }
2655
+ async function executeNonStreamingOperation(params) {
2656
+ const {
2657
+ operation,
2658
+ arg,
2659
+ callArgs,
2660
+ aiSDK,
2661
+ original,
2662
+ deps,
2663
+ sendEvents,
2664
+ sendTraces,
2665
+ selfDiagnostics,
2666
+ autoAttachmentEnabled,
2667
+ debug
2668
+ } = params;
2669
+ const inherited = await getCurrentParentSpanContext();
2670
+ const setup = setupOperation({
2671
+ operation,
2672
+ arg,
2673
+ inherited,
2674
+ aiSDK,
2675
+ options: deps.options,
2676
+ eventShipper: deps.eventShipper,
2677
+ traceShipper: deps.traceShipper,
2678
+ debug,
2679
+ selfDiagnostics,
2680
+ sendTraces
2681
+ });
2682
+ const finalize = createFinalize({
2683
+ operation,
2684
+ arg,
2685
+ setup,
2686
+ autoAttachmentEnabled,
2687
+ sendEvents,
2688
+ debug,
2689
+ options: deps.options,
2690
+ eventShipper: deps.eventShipper,
2691
+ traceShipper: deps.traceShipper
2692
+ });
2693
+ const callOriginal = async (...args) => {
2694
+ return await original.call(aiSDK, ...args);
2695
+ };
2696
+ try {
2697
+ const result = await runWithRootContextAsync(setup.rootSpan, setup.eventId, async () => {
2698
+ const nextArgs = [...callArgs];
2699
+ nextArgs[0] = setup.wrappedArgs;
2700
+ return await callOriginal(...nextArgs);
2701
+ });
2702
+ await safeFinalize(finalize, debug, result);
2703
+ return result;
2704
+ } catch (error) {
2705
+ await safeFinalize(finalize, debug, void 0, error);
2706
+ throw error;
2707
+ }
2708
+ }
2709
+ function wrapAISDK(aiSDK, deps) {
2710
+ var _a, _b, _c, _d;
2711
+ const debug = deps.eventShipper.isDebugEnabled() || deps.traceShipper.isDebugEnabled();
2712
+ if (deps.options.nativeTelemetry === true) {
2713
+ if (!hasStructuredTelemetryEvents(aiSDK)) {
2714
+ throw new Error(
2715
+ "[raindrop-ai/ai-sdk] nativeTelemetry requires AI SDK v7+. The AI SDK module passed to wrap() does not support structured telemetry events. Remove nativeTelemetry or upgrade to AI SDK v7."
2716
+ );
2717
+ }
2718
+ }
2719
+ const useNative = deps.options.nativeTelemetry === true;
2720
+ if (useNative) {
2721
+ const wrapTimeCtx = resolveContext(deps.options.context, { operation: "wrap", args: void 0 });
2722
+ const integration = new RaindropTelemetryIntegration({
2723
+ traceShipper: deps.traceShipper,
2724
+ eventShipper: deps.eventShipper,
2725
+ sendTraces: ((_a = deps.options.send) == null ? void 0 : _a.traces) !== false,
2726
+ sendEvents: ((_b = deps.options.send) == null ? void 0 : _b.events) !== false,
2727
+ debug,
2728
+ context: {
2729
+ userId: wrapTimeCtx.userId,
2730
+ eventId: wrapTimeCtx.eventId,
2731
+ eventName: wrapTimeCtx.eventName,
2732
+ convoId: wrapTimeCtx.convoId,
2733
+ properties: wrapTimeCtx.properties
2734
+ }
2735
+ });
2736
+ const registerFn = aiSDK["registerTelemetryIntegration"];
2737
+ if (isFunction(registerFn)) {
2738
+ registerFn(integration);
2739
+ }
2740
+ if (debug) {
2741
+ console.log("[raindrop-ai/ai-sdk] nativeTelemetry: registered RaindropTelemetryIntegration (no Proxy)");
2742
+ }
2743
+ const selfDiagnostics2 = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2744
+ if (selfDiagnostics2) {
2745
+ const textOps = /* @__PURE__ */ new Set(["generateText", "streamText"]);
2746
+ const jsonSchemaFactory = resolveJsonSchemaFactory(aiSDK);
2747
+ const proxyTarget2 = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
2748
+ return new Proxy(proxyTarget2, {
2749
+ get(target, prop, receiver) {
2750
+ const original = Reflect.get(target, prop, receiver);
2751
+ if (typeof prop !== "string" || !textOps.has(prop) || !isFunction(original)) {
2752
+ return original;
2753
+ }
2754
+ return (...callArgs) => {
2755
+ var _a2;
2756
+ const arg = callArgs[0];
2757
+ if (!isRecord(arg)) return original.call(aiSDK, ...callArgs);
2758
+ const telemetry = extractExperimentalTelemetry(arg);
2759
+ const callMeta = (telemetry == null ? void 0 : telemetry.metadata) ? extractRaindropMetadata(telemetry.metadata) : {};
2760
+ const perCallEventIdExplicit = (_a2 = callMeta.eventId) != null ? _a2 : wrapTimeCtx.eventId;
2761
+ const perCallEventId = perCallEventIdExplicit != null ? perCallEventIdExplicit : randomUUID();
2762
+ const perCallEventIdGenerated = !perCallEventIdExplicit;
2763
+ const perCallCtx = {
2764
+ eventId: perCallEventId,
2765
+ telemetry,
2766
+ sendTraces: false,
2767
+ debug,
2768
+ eventShipper: deps.eventShipper,
2769
+ traceShipper: deps.traceShipper,
2770
+ rootParentForChildren: void 0,
2771
+ jsonSchemaFactory,
2772
+ selfDiagnostics: selfDiagnostics2,
2773
+ aiSDKVersion: "7"
2774
+ };
2775
+ const tools = isRecord(arg["tools"]) ? { ...arg["tools"] } : {};
2776
+ const toolName = selfDiagnostics2.toolName;
2777
+ if (!(toolName in tools)) {
2778
+ const reportTool = createSelfDiagnosticsTool(perCallCtx);
2779
+ if (reportTool) tools[toolName] = reportTool;
2780
+ }
2781
+ const existingTelemetry = isRecord(arg["experimental_telemetry"]) ? arg["experimental_telemetry"] : {};
2782
+ const existingMetadata = isRecord(existingTelemetry["metadata"]) ? existingTelemetry["metadata"] : {};
2783
+ const mergedMetadata = existingMetadata["raindrop.eventId"] ? existingMetadata : {
2784
+ ...existingMetadata,
2785
+ "raindrop.eventId": perCallEventId,
2786
+ ...perCallEventIdGenerated ? { "raindrop.internal.eventIdGenerated": "true" } : {}
2787
+ };
2788
+ callArgs[0] = {
2789
+ ...arg,
2790
+ tools,
2791
+ experimental_telemetry: {
2792
+ ...existingTelemetry,
2793
+ metadata: mergedMetadata
2794
+ }
2795
+ };
2796
+ return original.call(aiSDK, ...callArgs);
2797
+ };
2798
+ }
2799
+ });
2800
+ }
2801
+ return aiSDK;
2802
+ }
2803
+ const instrumentedOps = /* @__PURE__ */ new Set([
2804
+ "generateText",
2805
+ "streamText",
2806
+ "generateObject",
2807
+ "streamObject"
2808
+ ]);
2809
+ const agentClasses = /* @__PURE__ */ new Set(["Agent", "Experimental_Agent", "ToolLoopAgent"]);
2810
+ const sendEvents = ((_c = deps.options.send) == null ? void 0 : _c.events) !== false;
2811
+ const sendTraces = ((_d = deps.options.send) == null ? void 0 : _d.traces) !== false;
2812
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
2813
+ const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2814
+ const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
2815
+ return new Proxy(proxyTarget, {
2816
+ get(target, prop, receiver) {
2817
+ const original = Reflect.get(target, prop, receiver);
2818
+ if (typeof prop === "string" && agentClasses.has(prop) && isAgentClass(original)) {
2819
+ if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping Agent class: ${prop}`);
2820
+ return wrapAgentClass(original, aiSDK, deps, debug, selfDiagnostics);
2821
+ }
2822
+ if (typeof prop !== "string" || !instrumentedOps.has(prop) || !isFunction(original)) {
2823
+ return original;
2824
+ }
2825
+ return (...callArgs) => {
2826
+ const operation = prop;
2827
+ const arg = callArgs[0];
2828
+ if (operation === "streamText" || operation === "streamObject") {
2829
+ return executeStreamingOperation({
2830
+ operation,
2831
+ arg,
2832
+ callArgs,
2833
+ aiSDK,
2834
+ original,
2835
+ deps,
2836
+ sendEvents,
2837
+ sendTraces,
2838
+ selfDiagnostics,
2839
+ autoAttachmentEnabled,
2840
+ debug
2841
+ });
2842
+ }
2843
+ return executeNonStreamingOperation({
2844
+ operation,
2845
+ arg,
2846
+ callArgs,
2847
+ aiSDK,
2848
+ original,
2849
+ deps,
2850
+ sendEvents,
2851
+ sendTraces,
2852
+ selfDiagnostics,
2853
+ autoAttachmentEnabled,
2854
+ debug
2855
+ });
2856
+ };
2857
+ }
2858
+ });
2859
+ }
2860
+ function wrapAgentClass(AgentClass, aiSDK, deps, debug, selfDiagnostics) {
2861
+ return new Proxy(AgentClass, {
2862
+ construct(target, args, newTarget) {
2863
+ const instance = Reflect.construct(target, args, newTarget);
2864
+ const agentSettings = args[0];
2865
+ const className = (newTarget == null ? void 0 : newTarget.name) || target.name || "Agent";
2866
+ if (debug) console.log(`[raindrop-ai/ai-sdk] Creating wrapped ${className} instance`);
2867
+ return new Proxy(instance, {
2868
+ get(instanceTarget, prop, instanceReceiver) {
2869
+ const original = Reflect.get(instanceTarget, prop, instanceReceiver);
2870
+ if (prop === "generate" && isFunction(original)) {
2871
+ if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping ${className}.generate method`);
2872
+ return wrapAgentGenerate(
2873
+ original,
2874
+ instanceTarget,
2875
+ agentSettings,
2876
+ className,
2877
+ aiSDK,
2878
+ deps,
2879
+ debug,
2880
+ selfDiagnostics
2881
+ );
2882
+ }
2883
+ if (prop === "stream" && isFunction(original)) {
2884
+ if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping ${className}.stream method`);
2885
+ return wrapAgentStream(
2886
+ original,
2887
+ instanceTarget,
2888
+ agentSettings,
2889
+ className,
2890
+ aiSDK,
2891
+ deps,
2892
+ debug,
2893
+ selfDiagnostics
2894
+ );
2895
+ }
2896
+ return original;
2897
+ }
2898
+ });
2899
+ }
2900
+ });
2901
+ }
2902
+ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
2903
+ var _a, _b;
2904
+ const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
2905
+ const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
2906
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
2907
+ return async (...callArgs) => {
2908
+ var _a2, _b2, _c, _d;
2909
+ const callParams = callArgs[0];
2910
+ const mergedArgs = { ...agentSettings, ...callParams };
2911
+ const operation = `${className}.generate`;
2912
+ const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
2913
+ const telemetry = extractExperimentalTelemetry(mergedArgs);
2914
+ const callTimeCtx = extractRaindropCallOptions(mergedArgs);
2915
+ const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
2916
+ if (!mergedCtx.userId) warnMissingUserIdOnce();
2917
+ const inherited = await getCurrentParentSpanContext();
2918
+ const eventId = (_c = (_b2 = (_a2 = callTimeCtx.eventId) != null ? _a2 : mergedCtx.eventId) != null ? _b2 : inherited == null ? void 0 : inherited.eventId) != null ? _c : randomUUID();
2919
+ const ctx = { ...mergedCtx};
2920
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
2921
+ const outerOperationId = `ai.${operation}`;
2922
+ const { operationName, resourceName } = opName(outerOperationId, telemetry == null ? void 0 : telemetry.functionId);
2923
+ const modelInfoFromArgs = extractModelInfo(mergedArgs["model"]);
2924
+ const rootSpan = sendTraces ? deps.traceShipper.startSpan({
2925
+ name: outerOperationId,
2926
+ parent: inheritedParent,
2927
+ eventId,
2928
+ operationId: outerOperationId,
2929
+ attributes: [
2930
+ attrString("operation.name", operationName),
2931
+ attrString("resource.name", resourceName),
2932
+ attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
2933
+ attrString("ai.model.provider", modelInfoFromArgs.provider),
2934
+ attrString("ai.model.id", modelInfoFromArgs.modelId),
2935
+ ...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
2936
+ ...attrsFromHeaders(mergedArgs["headers"]),
2937
+ ...attrsFromSettings(mergedArgs),
2938
+ ...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
2939
+ attrString(
2940
+ "ai.prompt",
2941
+ safeJsonWithUint8({
2942
+ system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"],
2943
+ prompt: mergedArgs["prompt"],
2944
+ messages: mergedArgs["messages"]
2945
+ })
2946
+ )
2947
+ ]
2948
+ ]
2949
+ }) : void 0;
2950
+ const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
2951
+ const wrapCtx = {
2952
+ eventId,
2953
+ telemetry,
2954
+ sendTraces,
2955
+ debug,
2956
+ eventShipper: deps.eventShipper,
2957
+ traceShipper: deps.traceShipper,
2958
+ rootParentForChildren,
2959
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2960
+ selfDiagnostics,
2961
+ aiSDKVersion: detectAISDKVersion(aiSDK)
2962
+ };
2963
+ const toolCalls = [];
2964
+ const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
2965
+ const mergedArgsWithWrappedModel = wrapModel(
2966
+ mergedArgsWithWrappedTools,
2967
+ aiSDK,
2968
+ outerOperationId,
2969
+ wrapCtx
2970
+ );
2971
+ const callParamsWithWrappedToolsAndModel = mergedArgsWithWrappedModel != null ? mergedArgsWithWrappedModel : {};
2972
+ const finalize = async (result, error) => {
2973
+ var _a3, _b3, _c2;
2974
+ const usage = extractUsageMetrics(result);
2975
+ const model = extractModel(result);
2976
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(mergedArgs) : void 0;
2977
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
2978
+ const baseMessages = coerceMessagesFromArgs(mergedArgs);
2979
+ const responseMessages = extractResponseMessages(result);
2980
+ const allMessages = [...baseMessages, ...responseMessages];
2981
+ const outputText = extractTextOutput(result);
2982
+ const defaultPatch = {
2983
+ eventName: (_a3 = ctx.eventName) != null ? _a3 : operation,
2984
+ input: (_b3 = lastUserMessageTextFromArgs(mergedArgs)) != null ? _b3 : extractInputFromArgs(mergedArgs),
2985
+ output: outputText,
2986
+ model,
2987
+ properties: ctx.properties,
2988
+ attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
2989
+ };
2990
+ const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
2991
+ const patch = mergeBuildEventPatch(defaultPatch, built);
2992
+ const output = patch.output;
2993
+ const finalModel = (_c2 = patch.model) != null ? _c2 : model;
2994
+ if (rootSpan) {
2995
+ const spanEndTimeUnixNano = nowUnixNanoString();
2996
+ const syntheticToolCallCount = emitTranscriptToolCallSpans({
2997
+ baseMessages,
2998
+ responseMessages,
2999
+ rootSpan,
3000
+ eventId,
3001
+ telemetry,
3002
+ toolCalls,
3003
+ traceShipper: deps.traceShipper,
3004
+ endTimeUnixNano: spanEndTimeUnixNano,
3005
+ keepEventPending: false
3006
+ });
3007
+ const finishReason = extractFinishReason(result);
3008
+ const providerMetadata = isRecord(result) ? result["providerMetadata"] : void 0;
3009
+ const resultToolCalls = isRecord(result) && Array.isArray(result["toolCalls"]) ? safeJsonWithUint8(result["toolCalls"]) : toolCalls.length ? safeJsonWithUint8(toolCalls) : void 0;
3010
+ deps.traceShipper.endSpan(rootSpan, {
3011
+ attributes: [
3012
+ ...(telemetry == null ? void 0 : telemetry.recordOutputs) === false ? [] : [
3013
+ attrString("ai.response.finishReason", finishReason),
3014
+ attrString("ai.response.text", output),
3015
+ attrString("ai.response.toolCalls", resultToolCalls),
3016
+ attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
3017
+ ],
3018
+ attrInt("ai.usage.promptTokens", usage == null ? void 0 : usage.inputTokens),
3019
+ attrInt("ai.usage.completionTokens", usage == null ? void 0 : usage.outputTokens),
3020
+ attrInt("ai.usage.inputTokens", usage == null ? void 0 : usage.inputTokens),
3021
+ attrInt("ai.usage.outputTokens", usage == null ? void 0 : usage.outputTokens),
3022
+ attrInt("ai.usage.totalTokens", usage == null ? void 0 : usage.totalTokens),
3023
+ attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
3024
+ attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
3025
+ attrInt("ai.toolCall.count", toolCalls.length + syntheticToolCallCount),
3026
+ ...error ? [
3027
+ attrString(
3028
+ "error.message",
3029
+ error instanceof Error ? error.message : String(error)
3030
+ )
3031
+ ] : []
3032
+ ],
3033
+ error,
3034
+ endTimeUnixNano: spanEndTimeUnixNano
3035
+ });
3036
+ }
3037
+ if (sendEvents) {
3038
+ if (debug) {
3039
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} shipping event:`, {
3040
+ eventId,
3041
+ eventName: patch.eventName,
3042
+ userId: ctx.userId,
3043
+ hasOutput: !!output
3044
+ });
3045
+ }
3046
+ void deps.eventShipper.patch(eventId, {
3047
+ eventName: patch.eventName,
3048
+ userId: ctx.userId,
3049
+ convoId: ctx.convoId,
3050
+ input: patch.input,
3051
+ output,
3052
+ model: finalModel,
3053
+ properties: patch.properties,
3054
+ attachments: patch.attachments,
3055
+ isPending: false
3056
+ }).catch((err) => {
3057
+ if (debug)
3058
+ console.warn(
3059
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
3060
+ );
3061
+ });
3062
+ } else if (debug) {
3063
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} sendEvents=false, skipping event`);
3064
+ }
3065
+ };
3066
+ const runWithContext = async (fn) => {
3067
+ if (!rootSpan) return await fn();
3068
+ return await runWithParentSpanContext(
3069
+ { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64, eventId },
3070
+ fn
3071
+ );
3072
+ };
3073
+ if (debug) {
3074
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} starting with context:`, {
3075
+ userId: ctx.userId,
3076
+ eventId,
3077
+ eventName: ctx.eventName
3078
+ });
3079
+ }
3080
+ try {
3081
+ const result = await runWithContext(async () => {
3082
+ return await generate.call(instance, callParamsWithWrappedToolsAndModel);
3083
+ });
3084
+ if (debug) {
3085
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} completed, finalizing...`);
3086
+ }
3087
+ try {
3088
+ await finalize(result);
3089
+ } catch (err) {
3090
+ if (debug)
3091
+ console.warn(
3092
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
3093
+ );
3094
+ }
3095
+ return result;
3096
+ } catch (error) {
3097
+ try {
3098
+ await finalize(void 0, error);
3099
+ } catch (err) {
3100
+ if (debug)
3101
+ console.warn(
3102
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
3103
+ );
3104
+ }
3105
+ throw error;
3106
+ }
3107
+ };
3108
+ }
3109
+ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
3110
+ var _a, _b;
3111
+ const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
3112
+ const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
3113
+ const autoAttachmentEnabled = deps.options.autoAttachment !== false;
3114
+ return async (...callArgs) => {
3115
+ var _a2, _b2, _c, _d;
3116
+ const callParams = callArgs[0];
3117
+ const mergedArgs = { ...agentSettings, ...callParams };
3118
+ const operation = `${className}.stream`;
3119
+ const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
3120
+ const telemetry = extractExperimentalTelemetry(mergedArgs);
3121
+ const callTimeCtx = extractRaindropCallOptions(mergedArgs);
3122
+ const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
3123
+ if (!mergedCtx.userId) warnMissingUserIdOnce();
3124
+ const inherited = await getCurrentParentSpanContext();
3125
+ const eventId = (_c = (_b2 = (_a2 = callTimeCtx.eventId) != null ? _a2 : mergedCtx.eventId) != null ? _b2 : inherited == null ? void 0 : inherited.eventId) != null ? _c : randomUUID();
3126
+ const ctx = { ...mergedCtx};
3127
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
3128
+ const outerOperationId = `ai.${operation}`;
3129
+ const { operationName, resourceName } = opName(outerOperationId, telemetry == null ? void 0 : telemetry.functionId);
3130
+ const modelInfoFromArgs = extractModelInfo(mergedArgs["model"]);
3131
+ const rootSpan = sendTraces ? deps.traceShipper.startSpan({
3132
+ name: outerOperationId,
3133
+ parent: inheritedParent,
3134
+ eventId,
3135
+ operationId: outerOperationId,
3136
+ attributes: [
3137
+ attrString("operation.name", operationName),
3138
+ attrString("resource.name", resourceName),
3139
+ attrString("ai.telemetry.functionId", telemetry == null ? void 0 : telemetry.functionId),
3140
+ attrString("ai.model.provider", modelInfoFromArgs.provider),
3141
+ attrString("ai.model.id", modelInfoFromArgs.modelId),
3142
+ ...attrsFromTelemetryMetadata(telemetry == null ? void 0 : telemetry.metadata),
3143
+ ...attrsFromHeaders(mergedArgs["headers"]),
3144
+ ...attrsFromSettings(mergedArgs),
3145
+ ...(telemetry == null ? void 0 : telemetry.recordInputs) === false ? [] : [
3146
+ attrString(
3147
+ "ai.prompt",
3148
+ safeJsonWithUint8({
3149
+ system: (_d = mergedArgs["system"]) != null ? _d : mergedArgs["instructions"],
3150
+ prompt: mergedArgs["prompt"],
3151
+ messages: mergedArgs["messages"]
3152
+ })
3153
+ )
3154
+ ]
3155
+ ]
3156
+ }) : void 0;
3157
+ const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
3158
+ const wrapCtx = {
3159
+ eventId,
3160
+ telemetry,
3161
+ sendTraces,
3162
+ debug,
3163
+ eventShipper: deps.eventShipper,
3164
+ traceShipper: deps.traceShipper,
3165
+ rootParentForChildren,
3166
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
3167
+ selfDiagnostics,
3168
+ aiSDKVersion: detectAISDKVersion(aiSDK)
3169
+ };
3170
+ const toolCalls = [];
3171
+ const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
3172
+ const mergedArgsWithWrappedModel = wrapModel(
3173
+ mergedArgsWithWrappedTools,
3174
+ aiSDK,
3175
+ outerOperationId,
3176
+ wrapCtx
3177
+ );
3178
+ const callParamsWithWrappedToolsAndModel = mergedArgsWithWrappedModel != null ? mergedArgsWithWrappedModel : {};
3179
+ const finalize = async (result, error) => {
3180
+ var _a3, _b3, _c2;
3181
+ const usage = extractUsageMetrics(result);
3182
+ const model = extractModel(result);
3183
+ const inputAttachments = autoAttachmentEnabled ? extractInputAttachmentsFromArgs(mergedArgs) : void 0;
3184
+ const outputAttachments = autoAttachmentEnabled ? await extractOutputAttachmentsFromResult(result) : void 0;
3185
+ const baseMessages = coerceMessagesFromArgs(mergedArgs);
3186
+ const responseMessages = extractResponseMessages(result);
3187
+ const allMessages = [...baseMessages, ...responseMessages];
3188
+ const outputText = extractTextOutput(result);
3189
+ const defaultPatch = {
3190
+ eventName: (_a3 = ctx.eventName) != null ? _a3 : operation,
3191
+ input: (_b3 = lastUserMessageTextFromArgs(mergedArgs)) != null ? _b3 : extractInputFromArgs(mergedArgs),
3192
+ output: outputText,
3193
+ model,
3194
+ properties: ctx.properties,
3195
+ attachments: mergeAttachments(ctx.attachments, inputAttachments, outputAttachments)
3196
+ };
3197
+ const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
3198
+ const patch = mergeBuildEventPatch(defaultPatch, built);
3199
+ const output = patch.output;
3200
+ const finalModel = (_c2 = patch.model) != null ? _c2 : model;
3201
+ if (rootSpan) {
3202
+ const spanEndTimeUnixNano = nowUnixNanoString();
3203
+ const syntheticToolCallCount = emitTranscriptToolCallSpans({
3204
+ baseMessages,
3205
+ responseMessages,
3206
+ rootSpan,
3207
+ eventId,
3208
+ telemetry,
3209
+ toolCalls,
3210
+ traceShipper: deps.traceShipper,
3211
+ endTimeUnixNano: spanEndTimeUnixNano,
3212
+ keepEventPending: false
3213
+ });
3214
+ const finishReason = extractFinishReason(result);
3215
+ const providerMetadata = isRecord(result) ? result["providerMetadata"] : void 0;
3216
+ const resultToolCalls = isRecord(result) && Array.isArray(result["toolCalls"]) ? safeJsonWithUint8(result["toolCalls"]) : toolCalls.length ? safeJsonWithUint8(toolCalls) : void 0;
3217
+ deps.traceShipper.endSpan(rootSpan, {
3218
+ attributes: [
3219
+ ...(telemetry == null ? void 0 : telemetry.recordOutputs) === false ? [] : [
3220
+ attrString("ai.response.finishReason", finishReason),
3221
+ attrString("ai.response.text", output),
3222
+ attrString("ai.response.toolCalls", resultToolCalls),
3223
+ attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
3224
+ ],
3225
+ attrInt("ai.usage.promptTokens", usage == null ? void 0 : usage.inputTokens),
3226
+ attrInt("ai.usage.completionTokens", usage == null ? void 0 : usage.outputTokens),
3227
+ attrInt("ai.usage.inputTokens", usage == null ? void 0 : usage.inputTokens),
3228
+ attrInt("ai.usage.outputTokens", usage == null ? void 0 : usage.outputTokens),
3229
+ attrInt("ai.usage.totalTokens", usage == null ? void 0 : usage.totalTokens),
3230
+ attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
3231
+ attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
3232
+ attrInt("ai.toolCall.count", toolCalls.length + syntheticToolCallCount),
3233
+ ...error ? [
3234
+ attrString(
3235
+ "error.message",
3236
+ error instanceof Error ? error.message : String(error)
3237
+ )
3238
+ ] : []
3239
+ ],
3240
+ error,
3241
+ endTimeUnixNano: spanEndTimeUnixNano
3242
+ });
3243
+ }
3244
+ if (sendEvents) {
3245
+ if (debug) {
3246
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} shipping event:`, {
3247
+ eventId,
3248
+ eventName: patch.eventName,
3249
+ userId: ctx.userId,
3250
+ hasOutput: !!output
3251
+ });
3252
+ }
3253
+ void deps.eventShipper.patch(eventId, {
3254
+ eventName: patch.eventName,
3255
+ userId: ctx.userId,
3256
+ convoId: ctx.convoId,
3257
+ input: patch.input,
3258
+ output,
3259
+ model: finalModel,
3260
+ properties: patch.properties,
3261
+ attachments: patch.attachments,
3262
+ isPending: false
3263
+ }).catch((err) => {
3264
+ if (debug)
3265
+ console.warn(
3266
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
3267
+ );
3268
+ });
3269
+ } else if (debug) {
3270
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} sendEvents=false, skipping event`);
3271
+ }
3272
+ };
3273
+ const runWithContext = async (fn) => {
3274
+ if (!rootSpan) return await fn();
3275
+ return await runWithParentSpanContext(
3276
+ { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64, eventId },
3277
+ fn
3278
+ );
3279
+ };
3280
+ if (debug) {
3281
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} starting with context:`, {
3282
+ userId: ctx.userId,
3283
+ eventId,
3284
+ eventName: ctx.eventName
3285
+ });
3286
+ }
3287
+ const callParamsWithOnFinish = wrapOnFinish(
3288
+ callParamsWithWrappedToolsAndModel != null ? callParamsWithWrappedToolsAndModel : {},
3289
+ async (result) => {
3290
+ if (debug) {
3291
+ console.log(`[raindrop-ai/ai-sdk] Agent ${operation} onFinish callback, finalizing...`);
3292
+ }
3293
+ try {
3294
+ await finalize(result);
3295
+ } catch (err) {
3296
+ if (debug)
3297
+ console.warn(
3298
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
3299
+ );
3300
+ }
3301
+ }
3302
+ );
3303
+ try {
3304
+ const result = await runWithContext(async () => {
3305
+ return await stream.call(instance, callParamsWithOnFinish);
3306
+ });
3307
+ return result;
3308
+ } catch (error) {
3309
+ try {
3310
+ await finalize(void 0, error);
3311
+ } catch (err) {
3312
+ if (debug)
3313
+ console.warn(
3314
+ `[raindrop-ai/ai-sdk] finalize failed: ${err instanceof Error ? err.message : err}`
3315
+ );
3316
+ }
3317
+ throw error;
3318
+ }
3319
+ };
3320
+ }
3321
+ function wrapTools(args, ctx, toolCalls) {
3322
+ if (!isRecord(args)) return args;
3323
+ const tools = isRecord(args["tools"]) ? { ...args["tools"] } : {};
3324
+ if (ctx.selfDiagnostics) {
3325
+ const reportToolName = ctx.selfDiagnostics.toolName;
3326
+ if (!(reportToolName in tools)) {
3327
+ const reportTool = createSelfDiagnosticsTool(ctx);
3328
+ if (reportTool !== void 0) {
3329
+ tools[reportToolName] = reportTool;
3330
+ }
3331
+ } else if (ctx.debug) {
3332
+ console.warn(
3333
+ `[raindrop-ai/ai-sdk] selfDiagnostics skipped: tool name collision for "${reportToolName}"`
3334
+ );
3335
+ }
3336
+ }
3337
+ if (Object.keys(tools).length === 0) return args;
3338
+ const wrapped = {};
3339
+ for (const [name, tool] of Object.entries(tools)) {
3340
+ wrapped[name] = wrapToolExecute(name, tool, ctx, toolCalls);
3341
+ }
3342
+ return { ...args, tools: wrapped };
3343
+ }
3344
+ function wrapToolExecute(name, tool, ctx, toolCalls) {
3345
+ var _a;
3346
+ if (!isRecord(tool) || !isFunction(tool["execute"])) return tool;
3347
+ const originalExecute = tool["execute"];
3348
+ const { operationName, resourceName } = opName("ai.toolCall", (_a = ctx.telemetry) == null ? void 0 : _a.functionId);
3349
+ const createToolSpan = (toolCallId, toolArgs, parent) => {
3350
+ var _a2, _b;
3351
+ if (!ctx.sendTraces || !parent) return void 0;
3352
+ return ctx.traceShipper.startSpan({
3353
+ name: "ai.toolCall",
3354
+ parent,
3355
+ eventId: ctx.eventId,
3356
+ operationId: "ai.toolCall",
3357
+ attributes: [
3358
+ attrString("operation.name", operationName),
3359
+ attrString("resource.name", resourceName),
3360
+ attrString("ai.telemetry.functionId", (_a2 = ctx.telemetry) == null ? void 0 : _a2.functionId),
3361
+ attrString("ai.toolCall.name", name),
3362
+ attrString("ai.toolCall.id", toolCallId),
3363
+ ...((_b = ctx.telemetry) == null ? void 0 : _b.recordInputs) === false ? [] : [attrString("ai.toolCall.args", safeJsonWithUint8(toolArgs))]
3364
+ ]
3365
+ });
3366
+ };
3367
+ const endToolSpan = (span, result, error) => {
3368
+ var _a2;
3369
+ if (!span) return;
3370
+ if (error) {
3371
+ ctx.traceShipper.endSpan(span, {
3372
+ attributes: [
3373
+ attrString("error.message", error instanceof Error ? error.message : String(error))
3374
+ ],
3375
+ error
3376
+ });
3377
+ } else {
3378
+ ctx.traceShipper.endSpan(span, {
3379
+ attributes: ((_a2 = ctx.telemetry) == null ? void 0 : _a2.recordOutputs) === false ? [] : [attrString("ai.toolCall.result", safeJsonWithUint8(result))]
3380
+ });
3381
+ }
3382
+ };
3383
+ const createContextSpan = (span) => ({
3384
+ traceIdB64: span.ids.traceIdB64,
3385
+ spanIdB64: span.ids.spanIdB64,
3386
+ eventId: ctx.eventId
3387
+ });
3388
+ const wrappedExecute = function(...execArgs) {
3389
+ const toolArgs = execArgs[0];
3390
+ const execOptions = execArgs.length > 1 ? execArgs[1] : void 0;
3391
+ const toolCallId = isRecord(execOptions) && typeof execOptions["toolCallId"] === "string" ? execOptions["toolCallId"] : randomUUID();
3392
+ const result = originalExecute.apply(this, execArgs);
3393
+ if (isAsyncIterable(result)) {
3394
+ return (async function* () {
3395
+ const parentCtx = await getCurrentParentSpanContext();
3396
+ const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
3397
+ const toolSpan = createToolSpan(toolCallId, toolArgs, parent);
3398
+ try {
3399
+ let lastValue;
3400
+ const iterator = result[Symbol.asyncIterator]();
3401
+ const wrappedIterable = toolSpan ? asyncGeneratorWithCurrent(
3402
+ createContextSpan(toolSpan),
3403
+ iterator
3404
+ ) : {
3405
+ [Symbol.asyncIterator]: () => iterator
3406
+ };
3407
+ for await (const value of wrappedIterable) {
3408
+ lastValue = value;
3409
+ yield value;
3410
+ }
3411
+ toolCalls.push({ id: toolCallId, name, args: toolArgs, result: lastValue, status: "OK" });
3412
+ endToolSpan(toolSpan, lastValue);
3413
+ } catch (error) {
3414
+ toolCalls.push({ id: toolCallId, name, args: toolArgs, status: "ERROR" });
3415
+ endToolSpan(toolSpan, void 0, error);
3416
+ throw error;
3417
+ }
3418
+ })();
3419
+ }
3420
+ return (async () => {
3421
+ const parentCtx = await getCurrentParentSpanContext();
3422
+ const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
3423
+ const toolSpan = createToolSpan(toolCallId, toolArgs, parent);
3424
+ const run = async () => {
3425
+ try {
3426
+ const awaitedResult = await result;
3427
+ toolCalls.push({
3428
+ id: toolCallId,
3429
+ name,
3430
+ args: toolArgs,
3431
+ result: awaitedResult,
3432
+ status: "OK"
3433
+ });
3434
+ endToolSpan(toolSpan, awaitedResult);
3435
+ return awaitedResult;
3436
+ } catch (error) {
3437
+ toolCalls.push({ id: toolCallId, name, args: toolArgs, status: "ERROR" });
3438
+ endToolSpan(toolSpan, void 0, error);
3439
+ throw error;
3440
+ }
3441
+ };
3442
+ if (!toolSpan) return await run();
3443
+ return await runWithParentSpanContext(
3444
+ {
3445
+ traceIdB64: toolSpan.ids.traceIdB64,
3446
+ spanIdB64: toolSpan.ids.spanIdB64,
3447
+ eventId: ctx.eventId
3448
+ },
3449
+ run
3450
+ );
3451
+ })();
3452
+ };
3453
+ return { ...tool, execute: wrappedExecute };
3454
+ }
3455
+ function wrapModel(args, aiSDK, outerOperationId, ctx) {
3456
+ if (!isRecord(args) || !("model" in args)) return args;
3457
+ let model = args["model"];
3458
+ if (typeof model === "string") {
3459
+ const maybeProvider = globalThis.AI_SDK_DEFAULT_PROVIDER;
3460
+ const gateway = isRecord(aiSDK) ? aiSDK["gateway"] : void 0;
3461
+ const provider = maybeProvider != null ? maybeProvider : gateway;
3462
+ if (isRecord(provider) && isFunction(provider["languageModel"])) {
3463
+ try {
3464
+ model = provider["languageModel"](model);
3465
+ } catch (e) {
3466
+ }
3467
+ }
3468
+ }
3469
+ if (!isRecord(model)) return args;
3470
+ const modelInfo = extractModelInfo(model);
3471
+ const doGenerateOpId = `${outerOperationId}.doGenerate`;
3472
+ const doStreamOpId = `${outerOperationId}.doStream`;
3473
+ const wrappedModel = new Proxy(model, {
3474
+ get(target, prop, receiver) {
3475
+ const original = Reflect.get(target, prop, receiver);
3476
+ if (prop === "doGenerate" && isFunction(original)) {
3477
+ return async (...callArgs) => {
3478
+ const options = callArgs[0];
3479
+ const parentCtx = await getCurrentParentSpanContext();
3480
+ const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
3481
+ const span = ctx.sendTraces && parent ? startDoGenerateSpan(doGenerateOpId, options, modelInfo, parent, ctx) : void 0;
3482
+ try {
3483
+ const result = await original.apply(target, callArgs);
3484
+ if (span) endDoGenerateSpan(span, result, modelInfo, ctx);
3485
+ return result;
3486
+ } catch (error) {
3487
+ if (span)
3488
+ ctx.traceShipper.endSpan(span, {
3489
+ attributes: [
3490
+ attrString(
3491
+ "error.message",
3492
+ error instanceof Error ? error.message : String(error)
3493
+ )
3494
+ ],
3495
+ error
3496
+ });
3497
+ throw error;
3498
+ }
3499
+ };
3500
+ }
3501
+ if (prop === "doStream" && isFunction(original)) {
3502
+ return async (...callArgs) => {
3503
+ const options = callArgs[0];
3504
+ const parentCtx = await getCurrentParentSpanContext();
3505
+ const parent = parentCtx && parentCtx.eventId === ctx.eventId ? { traceIdB64: parentCtx.traceIdB64, spanIdB64: parentCtx.spanIdB64 } : ctx.rootParentForChildren;
3506
+ const span = ctx.sendTraces && parent ? startDoStreamSpan(doStreamOpId, options, modelInfo, parent, ctx) : void 0;
3507
+ const startMs = Date.now();
3508
+ let firstChunkMs;
3509
+ let finishMs;
3510
+ let finishReason;
3511
+ let responseId;
3512
+ let responseModelId;
3513
+ let responseTimestampIso;
3514
+ let providerMetadata;
3515
+ let usage;
3516
+ let activeText = "";
3517
+ const toolCallsLocal = [];
3518
+ let result;
3519
+ try {
3520
+ result = await original.apply(target, callArgs);
3521
+ } catch (error) {
3522
+ if (span)
3523
+ ctx.traceShipper.endSpan(span, {
3524
+ attributes: [
3525
+ attrString(
3526
+ "error.message",
3527
+ error instanceof Error ? error.message : String(error)
3528
+ )
3529
+ ],
3530
+ error
3531
+ });
3532
+ throw error;
3533
+ }
3534
+ const stream = isRecord(result) ? result["stream"] : void 0;
3535
+ const RS = globalThis.ReadableStream;
3536
+ if (!RS || !(stream instanceof RS)) {
3537
+ if (span) ctx.traceShipper.endSpan(span);
3538
+ return result;
3539
+ }
3540
+ const reader = stream.getReader();
3541
+ let ended = false;
3542
+ const endSpan = (error) => {
3543
+ var _a;
3544
+ if (ended || !span) return;
3545
+ ended = true;
3546
+ const msToFirstChunk = firstChunkMs !== void 0 ? firstChunkMs - startMs : void 0;
3547
+ const msToFinish = finishMs !== void 0 ? finishMs - startMs : void 0;
3548
+ const inputTokens = extractNestedTokens(usage, "inputTokens");
3549
+ const outputTokens = extractNestedTokens(usage, "outputTokens");
3550
+ const avgOutTokensPerSecond = msToFinish && outputTokens !== void 0 && msToFinish > 0 ? 1e3 * outputTokens / msToFinish : void 0;
3551
+ ctx.traceShipper.endSpan(span, {
3552
+ attributes: [
3553
+ ...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
3554
+ attrString("ai.response.finishReason", finishReason),
3555
+ attrString("ai.response.text", activeText.length ? activeText : void 0),
3556
+ attrString(
3557
+ "ai.response.toolCalls",
3558
+ safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
3559
+ ),
3560
+ attrString("ai.response.id", responseId),
3561
+ attrString("ai.response.model", responseModelId),
3562
+ attrString("ai.response.timestamp", responseTimestampIso),
3563
+ attrString(
3564
+ "ai.response.providerMetadata",
3565
+ safeJsonWithUint8(providerMetadata)
3566
+ )
3567
+ ],
3568
+ attrInt("ai.usage.inputTokens", inputTokens),
3569
+ attrInt("ai.usage.outputTokens", outputTokens),
3570
+ ...finishReason ? [attrStringArray("gen_ai.response.finish_reasons", [finishReason])] : [],
3571
+ attrString("gen_ai.response.id", responseId),
3572
+ attrString("gen_ai.response.model", responseModelId),
3573
+ attrInt("gen_ai.usage.input_tokens", inputTokens),
3574
+ attrInt("gen_ai.usage.output_tokens", outputTokens),
3575
+ ...msToFirstChunk !== void 0 ? [attrInt("ai.stream.msToFirstChunk", msToFirstChunk)] : [],
3576
+ ...msToFinish !== void 0 ? [attrInt("ai.stream.msToFinish", msToFinish)] : [],
3577
+ ...avgOutTokensPerSecond !== void 0 ? [attrDouble("ai.stream.avgOutputTokensPerSecond", avgOutTokensPerSecond)] : [],
3578
+ ...error ? [
3579
+ attrString(
3580
+ "error.message",
3581
+ error instanceof Error ? error.message : String(error)
3582
+ )
3583
+ ] : []
3584
+ ],
3585
+ error
3586
+ });
3587
+ };
3588
+ const wrappedStream = new RS({
3589
+ async pull(controller) {
3590
+ try {
3591
+ const { done, value } = await reader.read();
3592
+ if (done) {
3593
+ finishMs = Date.now();
3594
+ endSpan();
3595
+ controller.close();
3596
+ return;
3597
+ }
3598
+ if (firstChunkMs === void 0) firstChunkMs = Date.now();
3599
+ if (isRecord(value)) {
3600
+ const type = value["type"];
3601
+ if (type === "text-delta") {
3602
+ let textDelta;
3603
+ if (typeof value["delta"] === "string") {
3604
+ textDelta = value["delta"];
3605
+ } else if (typeof value["textDelta"] === "string") {
3606
+ textDelta = value["textDelta"];
3607
+ }
3608
+ if (typeof textDelta === "string") activeText += textDelta;
3609
+ }
3610
+ if (type === "finish") finishReason = extractFinishReason(value);
3611
+ if (type === "tool-call") toolCallsLocal.push(value);
3612
+ if ("response" in value && isRecord(value["response"])) {
3613
+ const response = value["response"];
3614
+ if (typeof response["id"] === "string") responseId = response["id"];
3615
+ if (typeof response["modelId"] === "string")
3616
+ responseModelId = response["modelId"];
3617
+ if (response["timestamp"] instanceof Date)
3618
+ responseTimestampIso = response["timestamp"].toISOString();
3619
+ else if (typeof response["timestamp"] === "string")
3620
+ responseTimestampIso = response["timestamp"];
3621
+ }
3622
+ if ("usage" in value) usage = value["usage"];
3623
+ if ("providerMetadata" in value) providerMetadata = value["providerMetadata"];
3624
+ }
3625
+ controller.enqueue(value);
3626
+ } catch (error) {
3627
+ endSpan(error);
3628
+ controller.error(error);
3629
+ }
3630
+ },
3631
+ cancel(reason) {
3632
+ void reader.cancel(reason);
3633
+ endSpan(reason);
3634
+ }
3635
+ });
3636
+ return { ...result, stream: wrappedStream };
3637
+ };
3638
+ }
3639
+ return original;
3640
+ }
3641
+ });
3642
+ return { ...args, model: wrappedModel };
3643
+ }
3644
+ function startDoGenerateSpan(operationId, options, modelInfo, parent, ctx) {
3645
+ var _a, _b, _c;
3646
+ const { operationName, resourceName } = opName(operationId, (_a = ctx.telemetry) == null ? void 0 : _a.functionId);
3647
+ const tools = isRecord(options) ? options["tools"] : void 0;
3648
+ const toolsJson = Array.isArray(tools) && tools.length ? tools.map((tool) => safeJsonWithUint8(tool)).filter((json) => typeof json === "string" && json.length > 0) : void 0;
3649
+ const toolChoiceJson = isRecord(options) ? safeJsonWithUint8(options["toolChoice"]) : void 0;
3650
+ const promptJson = isRecord(options) ? safeJsonWithUint8(options["prompt"]) : safeJsonWithUint8(options);
3651
+ return ctx.traceShipper.startSpan({
3652
+ name: operationId,
3653
+ parent,
3654
+ eventId: ctx.eventId,
3655
+ operationId,
3656
+ attributes: [
3657
+ attrString("operation.name", operationName),
3658
+ attrString("resource.name", resourceName),
3659
+ attrString("ai.telemetry.functionId", (_b = ctx.telemetry) == null ? void 0 : _b.functionId),
3660
+ attrString("ai.model.provider", modelInfo.provider),
3661
+ attrString("ai.model.id", modelInfo.modelId),
3662
+ ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [
3663
+ attrString("ai.prompt.messages", promptJson),
3664
+ attrStringArray("ai.prompt.tools", toolsJson),
3665
+ attrString("ai.prompt.toolChoice", toolChoiceJson)
3666
+ ],
3667
+ attrString("gen_ai.system", modelInfo.provider),
3668
+ attrString("gen_ai.request.model", modelInfo.modelId),
3669
+ ...attrsFromGenAiRequest(options)
3670
+ ]
3671
+ });
3672
+ }
3673
+ function endDoGenerateSpan(span, result, modelInfo, ctx) {
3674
+ var _a;
3675
+ const finishReason = extractFinishReason(result);
3676
+ const content = isRecord(result) ? result["content"] : void 0;
3677
+ const response = isRecord(result) ? result["response"] : void 0;
3678
+ const usage = isRecord(result) ? result["usage"] : void 0;
3679
+ const providerMetadata = isRecord(result) ? result["providerMetadata"] : void 0;
3680
+ let responseId;
3681
+ if (isRecord(response) && typeof response["id"] === "string") {
3682
+ responseId = response["id"];
3683
+ } else {
3684
+ responseId = randomUUID();
3685
+ }
3686
+ let responseModelId;
3687
+ if (isRecord(response) && typeof response["modelId"] === "string") {
3688
+ responseModelId = response["modelId"];
3689
+ } else {
3690
+ responseModelId = modelInfo.modelId;
3691
+ }
3692
+ let responseTimestampIso;
3693
+ if (isRecord(response) && response["timestamp"] instanceof Date) {
3694
+ responseTimestampIso = response["timestamp"].toISOString();
3695
+ } else if (isRecord(response) && typeof response["timestamp"] === "string") {
3696
+ responseTimestampIso = response["timestamp"];
3697
+ } else {
3698
+ responseTimestampIso = (/* @__PURE__ */ new Date()).toISOString();
3699
+ }
3700
+ const inputTokens = extractNestedTokens(usage, "inputTokens");
3701
+ const outputTokens = extractNestedTokens(usage, "outputTokens");
3702
+ ctx.traceShipper.endSpan(span, {
3703
+ attributes: [
3704
+ ...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
3705
+ attrString("ai.response.finishReason", finishReason),
3706
+ attrString("ai.response.text", extractTextFromLmContent(content)),
3707
+ attrString(
3708
+ "ai.response.toolCalls",
3709
+ safeJsonWithUint8(extractToolCallsFromLmContent(content))
3710
+ ),
3711
+ attrString("ai.response.id", responseId),
3712
+ attrString("ai.response.model", responseModelId),
3713
+ attrString("ai.response.timestamp", responseTimestampIso),
3714
+ attrString("ai.response.providerMetadata", safeJsonWithUint8(providerMetadata))
3715
+ ],
3716
+ attrInt("ai.usage.promptTokens", inputTokens),
3717
+ attrInt("ai.usage.completionTokens", outputTokens),
3718
+ ...finishReason ? [attrStringArray("gen_ai.response.finish_reasons", [finishReason])] : [],
3719
+ attrString("gen_ai.response.id", responseId),
3720
+ attrString("gen_ai.response.model", responseModelId),
3721
+ attrInt("gen_ai.usage.input_tokens", inputTokens),
3722
+ attrInt("gen_ai.usage.output_tokens", outputTokens)
3723
+ ]
3724
+ });
3725
+ }
3726
+ function startDoStreamSpan(operationId, options, modelInfo, parent, ctx) {
3727
+ var _a, _b, _c;
3728
+ const { operationName, resourceName } = opName(operationId, (_a = ctx.telemetry) == null ? void 0 : _a.functionId);
3729
+ const tools = isRecord(options) ? options["tools"] : void 0;
3730
+ const toolsJson = Array.isArray(tools) && tools.length ? tools.map((tool) => safeJsonWithUint8(tool)).filter((json) => typeof json === "string" && json.length > 0) : void 0;
3731
+ const toolChoiceJson = isRecord(options) ? safeJsonWithUint8(options["toolChoice"]) : void 0;
3732
+ const promptJson = isRecord(options) ? safeJsonWithUint8(options["prompt"]) : safeJsonWithUint8(options);
3733
+ return ctx.traceShipper.startSpan({
3734
+ name: operationId,
3735
+ parent,
3736
+ eventId: ctx.eventId,
3737
+ operationId,
3738
+ attributes: [
3739
+ attrString("operation.name", operationName),
3740
+ attrString("resource.name", resourceName),
3741
+ attrString("ai.telemetry.functionId", (_b = ctx.telemetry) == null ? void 0 : _b.functionId),
3742
+ attrString("ai.model.provider", modelInfo.provider),
3743
+ attrString("ai.model.id", modelInfo.modelId),
3744
+ ...((_c = ctx.telemetry) == null ? void 0 : _c.recordInputs) === false ? [] : [
3745
+ attrString("ai.prompt.messages", promptJson),
3746
+ attrStringArray("ai.prompt.tools", toolsJson),
3747
+ attrString("ai.prompt.toolChoice", toolChoiceJson)
3748
+ ],
3749
+ attrString("gen_ai.system", modelInfo.provider),
3750
+ attrString("gen_ai.request.model", modelInfo.modelId),
3751
+ ...attrsFromGenAiRequest(options)
3752
+ ]
3753
+ });
3754
+ }
3755
+ function resolveContext(context, info) {
3756
+ if (context === void 0) return {};
3757
+ return typeof context === "function" ? context(info) : context;
3758
+ }
3759
+ function wrapOnFinish(args, onFinish) {
3760
+ if (!isRecord(args)) return args;
3761
+ const existing = args["onFinish"];
3762
+ if (existing === void 0) {
3763
+ return { ...args, onFinish: async (result) => onFinish(result) };
3764
+ }
3765
+ if (!isFunction(existing)) return args;
3766
+ return {
3767
+ ...args,
3768
+ onFinish: async (result) => {
3769
+ let userError;
3770
+ try {
3771
+ const maybePromise = existing(result);
3772
+ if (maybePromise && typeof maybePromise.then === "function") {
3773
+ await maybePromise;
3774
+ }
3775
+ } catch (error) {
3776
+ userError = error;
3777
+ }
3778
+ await onFinish(result);
3779
+ if (userError !== void 0) {
3780
+ throw userError;
3781
+ }
3782
+ }
3783
+ };
3784
+ }
3785
+ async function maybeBuildEvent(buildEvent, messages) {
3786
+ if (!buildEvent) return void 0;
3787
+ try {
3788
+ const r = buildEvent(messages);
3789
+ return r && typeof r === "object" ? r : void 0;
3790
+ } catch (e) {
3791
+ return void 0;
3792
+ }
3793
+ }
3794
+ function mergeBuildEventPatch(defaults, override) {
3795
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3796
+ if (!override) return defaults;
3797
+ return {
3798
+ eventName: (_a = override.eventName) != null ? _a : defaults.eventName,
3799
+ input: (_b = override.input) != null ? _b : defaults.input,
3800
+ output: (_c = override.output) != null ? _c : defaults.output,
3801
+ model: (_d = override.model) != null ? _d : defaults.model,
3802
+ properties: override.properties !== void 0 ? { ...(_e = defaults.properties) != null ? _e : {}, ...(_f = override.properties) != null ? _f : {} } : defaults.properties,
3803
+ attachments: override.attachments !== void 0 ? [...(_g = defaults.attachments) != null ? _g : [], ...(_h = override.attachments) != null ? _h : []] : defaults.attachments
3804
+ };
3805
+ }
3806
+ function mergeAttachments(...groups) {
3807
+ const merged = [];
3808
+ for (const group of groups) {
3809
+ if (group == null ? void 0 : group.length) merged.push(...group);
3810
+ }
3811
+ return merged.length ? merged : void 0;
3812
+ }
3813
+ function extractNestedTokens(usage, key) {
3814
+ if (!isRecord(usage)) return void 0;
3815
+ const val = usage[key];
3816
+ if (typeof val === "number") return val;
3817
+ if (isRecord(val) && typeof val["total"] === "number") return val["total"];
3818
+ return void 0;
3819
+ }
3820
+
3821
+ // src/index.ts
3822
+ function eventMetadata(options) {
3823
+ const result = {};
3824
+ if (options.eventId) {
3825
+ result["raindrop.eventId"] = options.eventId;
3826
+ } else {
3827
+ result["raindrop.eventId"] = randomUUID();
3828
+ result["raindrop.internal.eventIdGenerated"] = "true";
3829
+ }
3830
+ if (options.userId) result["raindrop.userId"] = options.userId;
3831
+ if (options.convoId) result["raindrop.convoId"] = options.convoId;
3832
+ if (options.eventName) result["raindrop.eventName"] = options.eventName;
3833
+ if (options.properties) result["raindrop.properties"] = JSON.stringify(options.properties);
3834
+ return result;
3835
+ }
3836
+ function deriveChatTurnMessageId(request) {
3837
+ const messages = Array.isArray(request.messages) ? request.messages : [];
3838
+ for (let i = messages.length - 1; i >= 0; i--) {
3839
+ const message = messages[i];
3840
+ if ((message == null ? void 0 : message.role) === "user" && typeof message.id === "string" && message.id.length > 0) {
3841
+ return message.id;
3842
+ }
3843
+ }
3844
+ if (typeof request.messageId === "string" && request.messageId.length > 0) {
3845
+ return request.messageId;
3846
+ }
3847
+ return void 0;
3848
+ }
3849
+ function eventMetadataFromChatRequest(options) {
3850
+ var _a, _b;
3851
+ const { request, ...rest } = options;
3852
+ const convoId = (_a = rest.convoId) != null ? _a : typeof request.id === "string" && request.id.length > 0 ? request.id : void 0;
3853
+ const turnMessageId = deriveChatTurnMessageId(request);
3854
+ const eventId = (_b = rest.eventId) != null ? _b : turnMessageId ? convoId ? `chat:${convoId}:${turnMessageId}` : `chat:${turnMessageId}` : void 0;
3855
+ return eventMetadata({
3856
+ ...rest,
3857
+ ...convoId ? { convoId } : {},
3858
+ ...eventId ? { eventId } : {}
3859
+ });
3860
+ }
3861
+ function envDebugEnabled() {
3862
+ var _a;
3863
+ if (typeof process === "undefined") return false;
3864
+ const flag = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
3865
+ return flag === "1" || flag === "true";
3866
+ }
3867
+ function createRaindropAISDK(opts) {
3868
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3869
+ const writeKey = opts.writeKey;
3870
+ const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
3871
+ const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
3872
+ const eventsEnabled = eventsRequested && !!writeKey;
3873
+ const tracesEnabled = tracesRequested && !!writeKey;
3874
+ const envDebug = envDebugEnabled();
3875
+ if (!writeKey && (eventsRequested || tracesRequested)) {
3876
+ console.warn(
3877
+ "[raindrop-ai/ai-sdk] writeKey not provided; telemetry shipping is disabled"
3878
+ );
3879
+ }
3880
+ const eventShipper = new EventShipper2({
3881
+ writeKey,
3882
+ endpoint: opts.endpoint,
3883
+ enabled: eventsEnabled,
3884
+ debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
3885
+ partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
3886
+ });
3887
+ const traceShipper = new TraceShipper2({
3888
+ writeKey,
3889
+ endpoint: opts.endpoint,
3890
+ enabled: tracesEnabled,
3891
+ debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
3892
+ debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true || envDebug,
3893
+ flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
3894
+ maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
3895
+ maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize
3896
+ });
3897
+ return {
3898
+ wrap(aiSDK, options) {
3899
+ return wrapAISDK(aiSDK, {
3900
+ options: options != null ? options : {},
3901
+ eventShipper,
3902
+ traceShipper
3903
+ });
3904
+ },
3905
+ createTelemetryIntegration(context) {
3906
+ return new RaindropTelemetryIntegration({
3907
+ traceShipper,
3908
+ eventShipper,
3909
+ sendTraces: tracesEnabled,
3910
+ sendEvents: eventsEnabled,
3911
+ debug: envDebug,
3912
+ context
3913
+ });
3914
+ },
3915
+ events: {
3916
+ async patch(eventId, patch) {
3917
+ await eventShipper.patch(eventId, patch);
3918
+ },
3919
+ async addAttachments(eventId, attachments) {
3920
+ await eventShipper.patch(eventId, { attachments });
3921
+ },
3922
+ async setProperties(eventId, properties) {
3923
+ await eventShipper.patch(eventId, { properties });
3924
+ },
3925
+ async finish(eventId, patch) {
3926
+ await eventShipper.finish(eventId, patch);
3927
+ }
3928
+ },
3929
+ users: {
3930
+ async identify(users) {
3931
+ await eventShipper.identify(users);
3932
+ }
3933
+ },
3934
+ signals: {
3935
+ async track(signal) {
3936
+ await eventShipper.trackSignal(signal);
3937
+ }
3938
+ },
3939
+ async flush() {
3940
+ await Promise.all([eventShipper.flush(), traceShipper.flush()]);
3941
+ },
3942
+ async shutdown() {
3943
+ await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
3944
+ }
3945
+ };
3946
+ }
3947
+
3948
+ export { RaindropTelemetryIntegration, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, eventMetadataFromChatRequest, getContextManager, withCurrent };