@raindrop-ai/ai-sdk 0.0.15 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,58 @@
1
- // src/internal/http.ts
1
+ // ../core/dist/chunk-FTBZHS25.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
+ }
2
56
  function wait(ms) {
3
57
  return new Promise((resolve) => setTimeout(resolve, ms));
4
58
  }
@@ -11,7 +65,7 @@ function parseRetryAfter(headers) {
11
65
  const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
12
66
  if (!value) return void 0;
13
67
  const asNumber = Number(value);
14
- if (!Number.isNaN(asNumber)) return asNumber * 1e3;
68
+ if (value.trim() !== "" && !Number.isNaN(asNumber)) return asNumber * 1e3;
15
69
  const asDate = new Date(value).getTime();
16
70
  if (!Number.isNaN(asDate)) {
17
71
  const delta = asDate - Date.now();
@@ -30,16 +84,19 @@ function getRetryDelayMs(attemptNumber, previousError) {
30
84
  return base * factor;
31
85
  }
32
86
  async function withRetry(operation, opName2, opts) {
87
+ const prefix = opts.sdkName ? `[raindrop-ai/${opts.sdkName}]` : "[raindrop-ai/core]";
33
88
  let lastError = void 0;
34
89
  for (let attemptNumber = 1; attemptNumber <= opts.maxAttempts; attemptNumber++) {
35
90
  if (attemptNumber > 1) {
36
91
  const delay = getRetryDelayMs(attemptNumber, lastError);
37
92
  if (opts.debug) {
38
- console.warn(`[raindrop-ai/ai-sdk] ${opName2} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`);
93
+ console.warn(
94
+ `${prefix} ${opName2} retry ${attemptNumber}/${opts.maxAttempts} in ${delay}ms`
95
+ );
39
96
  }
40
97
  if (delay > 0) await wait(delay);
41
98
  } else if (opts.debug) {
42
- console.log(`[raindrop-ai/ai-sdk] ${opName2} attempt ${attemptNumber}/${opts.maxAttempts}`);
99
+ console.log(`${prefix} ${opName2} attempt ${attemptNumber}/${opts.maxAttempts}`);
43
100
  }
44
101
  try {
45
102
  return await operation();
@@ -48,9 +105,11 @@ async function withRetry(operation, opName2, opts) {
48
105
  if (opts.debug) {
49
106
  const msg = err instanceof Error ? err.message : String(err);
50
107
  console.warn(
51
- `[raindrop-ai/ai-sdk] ${opName2} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
108
+ `${prefix} ${opName2} attempt ${attemptNumber} failed: ${msg}${attemptNumber === opts.maxAttempts ? " (no more retries)" : ""}`
52
109
  );
53
110
  }
111
+ if (lastError && typeof lastError === "object" && "retryable" in lastError && !lastError.retryable)
112
+ break;
54
113
  if (attemptNumber === opts.maxAttempts) break;
55
114
  }
56
115
  }
@@ -70,9 +129,12 @@ async function postJson(url, body, headers, opts) {
70
129
  });
71
130
  if (!resp.ok) {
72
131
  const text = await resp.text().catch(() => "");
73
- const err = new Error(`HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`);
132
+ const err = new Error(
133
+ `HTTP ${resp.status} ${resp.statusText}${text ? `: ${text}` : ""}`
134
+ );
74
135
  const retryAfterMs = parseRetryAfter(resp.headers);
75
136
  if (typeof retryAfterMs === "number") err.retryAfterMs = retryAfterMs;
137
+ err.retryable = resp.status === 429 || resp.status >= 500;
76
138
  throw err;
77
139
  }
78
140
  },
@@ -80,27 +142,81 @@ async function postJson(url, body, headers, opts) {
80
142
  opts
81
143
  );
82
144
  }
83
-
84
- // package.json
85
- var package_default = {
86
- name: "@raindrop-ai/ai-sdk",
87
- version: "0.0.15"};
88
-
89
- // src/internal/version.ts
90
- var libraryName = package_default.name;
91
- var libraryVersion = package_default.version;
92
-
93
- // src/internal/events.ts
94
- function getRuntimeContext() {
95
- const isNode = typeof process !== "undefined" && typeof process.version === "string";
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));
96
151
  return {
97
- library: { name: libraryName, version: libraryVersion },
98
- metadata: {
99
- jsRuntime: isNode ? "node" : "web",
100
- ...isNode ? { nodeVersion: process.version } : {}
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
+ }
101
186
  }
102
187
  };
103
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
+ }
104
220
  function mergePatches(target, source) {
105
221
  var _a, _b, _c, _d;
106
222
  const out = { ...target, ...source };
@@ -118,26 +234,39 @@ var EventShipper = class {
118
234
  this.sticky = /* @__PURE__ */ new Map();
119
235
  this.timers = /* @__PURE__ */ new Map();
120
236
  this.inFlight = /* @__PURE__ */ new Set();
121
- var _a, _b, _c;
122
- if (opts.enabled && !opts.writeKey) {
123
- throw new Error("[raindrop-ai/ai-sdk] writeKey is required when events are enabled");
124
- }
125
- this.writeKey = (_a = opts.writeKey) != null ? _a : "";
237
+ var _a, _b, _c, _d, _e, _f, _g;
238
+ this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
126
239
  this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
127
- this.enabled = opts.enabled;
240
+ this.enabled = opts.enabled !== false;
128
241
  this.debug = opts.debug;
129
242
  this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
130
- this.context = getRuntimeContext();
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
+ };
131
257
  }
132
258
  isDebugEnabled() {
133
259
  return this.debug;
134
260
  }
261
+ authHeaders() {
262
+ return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
263
+ }
135
264
  async patch(eventId, patch) {
136
265
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
137
266
  if (!this.enabled) return;
138
- if (!eventId) return;
267
+ if (!eventId || !eventId.trim()) return;
139
268
  if (this.debug) {
140
- console.log("[raindrop-ai/ai-sdk] queue patch", {
269
+ console.log(`${this.prefix} queue patch`, {
141
270
  eventId,
142
271
  userId: patch.userId,
143
272
  eventName: patch.eventName,
@@ -205,26 +334,23 @@ var EventShipper = class {
205
334
  ];
206
335
  const url = `${this.baseUrl}signals/track`;
207
336
  try {
208
- await postJson(
209
- url,
210
- body,
211
- { Authorization: `Bearer ${this.writeKey}` },
212
- { maxAttempts: 3, debug: this.debug }
213
- );
337
+ await postJson(url, body, this.authHeaders(), {
338
+ maxAttempts: 3,
339
+ debug: this.debug,
340
+ sdkName: this.sdkName
341
+ });
214
342
  } catch (err) {
215
- if (this.debug) {
216
- const msg = err instanceof Error ? err.message : String(err);
217
- console.warn(`[raindrop-ai/ai-sdk] failed to send signal (dropping): ${msg}`);
218
- }
343
+ const msg = err instanceof Error ? err.message : String(err);
344
+ console.warn(`${this.prefix} failed to send signal (dropping): ${msg}`);
219
345
  }
220
346
  }
221
347
  async identify(users) {
222
348
  if (!this.enabled) return;
223
349
  const list = Array.isArray(users) ? users : [users];
224
350
  const body = list.filter((user) => {
225
- if (!(user == null ? void 0 : user.userId)) {
351
+ if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
226
352
  if (this.debug) {
227
- console.warn("[raindrop-ai/ai-sdk] skipping identify: missing userId");
353
+ console.warn(`${this.prefix} skipping identify: missing userId`);
228
354
  }
229
355
  return false;
230
356
  }
@@ -239,17 +365,14 @@ var EventShipper = class {
239
365
  if (body.length === 0) return;
240
366
  const url = `${this.baseUrl}users/identify`;
241
367
  try {
242
- await postJson(
243
- url,
244
- body,
245
- { Authorization: `Bearer ${this.writeKey}` },
246
- { maxAttempts: 3, debug: this.debug }
247
- );
368
+ await postJson(url, body, this.authHeaders(), {
369
+ maxAttempts: 3,
370
+ debug: this.debug,
371
+ sdkName: this.sdkName
372
+ });
248
373
  } catch (err) {
249
- if (this.debug) {
250
- const msg = err instanceof Error ? err.message : String(err);
251
- console.warn(`[raindrop-ai/ai-sdk] failed to send identify (dropping): ${msg}`);
252
- }
374
+ const msg = err instanceof Error ? err.message : String(err);
375
+ console.warn(`${this.prefix} failed to send identify (dropping): ${msg}`);
253
376
  }
254
377
  }
255
378
  async flushOne(eventId) {
@@ -264,12 +387,13 @@ var EventShipper = class {
264
387
  this.buffers.delete(eventId);
265
388
  if (!accumulated) return;
266
389
  const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
267
- const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : "ai_generation";
390
+ const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
268
391
  const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
269
392
  if (!userId) {
270
393
  if (this.debug) {
271
- console.warn(`[raindrop-ai/ai-sdk] skipping track_partial for ${eventId}: missing userId`);
394
+ console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
272
395
  }
396
+ this.sticky.delete(eventId);
273
397
  return;
274
398
  }
275
399
  const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
@@ -294,7 +418,7 @@ var EventShipper = class {
294
418
  };
295
419
  const url = `${this.baseUrl}events/track_partial`;
296
420
  if (this.debug) {
297
- console.log("[raindrop-ai/ai-sdk] sending track_partial", {
421
+ console.log(`${this.prefix} sending track_partial`, {
298
422
  eventId,
299
423
  eventName,
300
424
  userId,
@@ -311,24 +435,21 @@ var EventShipper = class {
311
435
  endpoint: url
312
436
  });
313
437
  }
314
- const p = postJson(
315
- url,
316
- payload,
317
- { Authorization: `Bearer ${this.writeKey}` },
318
- { maxAttempts: 3, debug: this.debug }
319
- );
438
+ const p = postJson(url, payload, this.authHeaders(), {
439
+ maxAttempts: 3,
440
+ debug: this.debug,
441
+ sdkName: this.sdkName
442
+ });
320
443
  this.inFlight.add(p);
321
444
  try {
322
445
  try {
323
446
  await p;
324
447
  if (this.debug) {
325
- console.log(`[raindrop-ai/ai-sdk] sent track_partial ${eventId} (${eventName})`);
448
+ console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
326
449
  }
327
450
  } catch (err) {
328
- if (this.debug) {
329
- const msg = err instanceof Error ? err.message : String(err);
330
- console.warn(`[raindrop-ai/ai-sdk] failed to send track_partial (dropping): ${msg}`);
331
- }
451
+ const msg = err instanceof Error ? err.message : String(err);
452
+ console.warn(`${this.prefix} failed to send track_partial (dropping): ${msg}`);
332
453
  }
333
454
  } finally {
334
455
  this.inFlight.delete(p);
@@ -339,182 +460,50 @@ var EventShipper = class {
339
460
  }
340
461
  }
341
462
  };
342
-
343
- // src/internal/ids.ts
344
- function getCrypto() {
345
- const c = globalThis.crypto;
346
- return c;
347
- }
348
- function randomBytes(length) {
349
- const cryptoObj = getCrypto();
350
- const out = new Uint8Array(length);
351
- if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
352
- cryptoObj.getRandomValues(out);
353
- return out;
354
- }
355
- for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
356
- return out;
357
- }
358
- function randomUUID() {
359
- const cryptoObj = getCrypto();
360
- if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
361
- return cryptoObj.randomUUID();
362
- }
363
- const b = randomBytes(16);
364
- b[6] = b[6] & 15 | 64;
365
- b[8] = b[8] & 63 | 128;
366
- const hex = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
367
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
368
- }
369
- function base64Encode(bytes) {
370
- const maybeBuffer = globalThis.Buffer;
371
- if (maybeBuffer) {
372
- return maybeBuffer.from(bytes).toString("base64");
373
- }
374
- let binary = "";
375
- for (let i2 = 0; i2 < bytes.length; i2++) {
376
- binary += String.fromCharCode(bytes[i2]);
377
- }
378
- const btoaFn = globalThis.btoa;
379
- if (typeof btoaFn === "function") return btoaFn(binary);
380
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
381
- let out = "";
382
- let i = 0;
383
- while (i < binary.length) {
384
- const c1 = binary.charCodeAt(i++) & 255;
385
- const c2 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
386
- const c3 = i < binary.length ? binary.charCodeAt(i++) & 255 : NaN;
387
- const e1 = c1 >> 2;
388
- const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
389
- const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
390
- const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
391
- out += alphabet.charAt(e1);
392
- out += alphabet.charAt(e2);
393
- out += e3 === 64 ? "=" : alphabet.charAt(e3);
394
- out += e4 === 64 ? "=" : alphabet.charAt(e4);
395
- }
396
- return out;
397
- }
398
-
399
- // src/internal/otlp.ts
400
- var SpanStatusCode = {
401
- ERROR: 2
402
- };
403
- function createSpanIds(parent) {
404
- const traceId = parent ? parent.traceIdB64 : base64Encode(randomBytes(16));
405
- const spanId = base64Encode(randomBytes(8));
406
- return {
407
- traceIdB64: traceId,
408
- spanIdB64: spanId,
409
- parentSpanIdB64: parent ? parent.spanIdB64 : void 0
410
- };
411
- }
412
- function nowUnixNanoString() {
413
- return String(Date.now() * 1e6);
414
- }
415
- function attrString(key, value) {
416
- if (value === void 0) return void 0;
417
- return { key, value: { stringValue: value } };
418
- }
419
- function attrInt(key, value) {
420
- if (value === void 0) return void 0;
421
- if (!Number.isFinite(value)) return void 0;
422
- return { key, value: { intValue: String(Math.trunc(value)) } };
423
- }
424
- function attrDouble(key, value) {
425
- if (value === void 0) return void 0;
426
- if (!Number.isFinite(value)) return void 0;
427
- return { key, value: { doubleValue: value } };
428
- }
429
- function attrBool(key, value) {
430
- if (value === void 0) return void 0;
431
- return { key, value: { boolValue: value } };
432
- }
433
- function attrStringArray(key, values) {
434
- if (!values || values.length === 0) return void 0;
435
- return {
436
- key,
437
- value: {
438
- arrayValue: {
439
- values: values.filter((v) => typeof v === "string").map((v) => ({ stringValue: v }))
440
- }
441
- }
442
- };
443
- }
444
- function buildOtlpSpan(args) {
445
- const attrs = args.attributes.filter((x) => x !== void 0);
446
- const span = {
447
- traceId: args.ids.traceIdB64,
448
- spanId: args.ids.spanIdB64,
449
- name: args.name,
450
- startTimeUnixNano: args.startTimeUnixNano,
451
- endTimeUnixNano: args.endTimeUnixNano
452
- };
453
- if (args.ids.parentSpanIdB64) span.parentSpanId = args.ids.parentSpanIdB64;
454
- if (attrs.length) span.attributes = attrs;
455
- if (args.status) span.status = args.status;
456
- return span;
457
- }
458
- function buildExportTraceServiceRequest(spans) {
459
- return {
460
- resourceSpans: [
461
- {
462
- resource: {
463
- attributes: [{ key: "service.name", value: { stringValue: "raindrop.ai-sdk" } }]
464
- },
465
- scopeSpans: [
466
- {
467
- scope: { name: "raindrop.ai-sdk", version: libraryVersion },
468
- spans
469
- }
470
- ]
471
- }
472
- ]
473
- };
474
- }
475
-
476
- // src/internal/traces.ts
477
463
  var TraceShipper = class {
478
464
  constructor(opts) {
479
465
  this.queue = [];
480
466
  this.inFlight = /* @__PURE__ */ new Set();
481
- var _a, _b, _c, _d, _e;
482
- if (opts.enabled && !opts.writeKey) {
483
- throw new Error("[raindrop-ai/ai-sdk] writeKey is required when traces are enabled");
484
- }
485
- this.writeKey = (_a = opts.writeKey) != null ? _a : "";
467
+ var _a, _b, _c, _d, _e, _f, _g, _h;
468
+ this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
486
469
  this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
487
- this.enabled = opts.enabled;
470
+ this.enabled = opts.enabled !== false;
488
471
  this.debug = opts.debug;
489
472
  this.debugSpans = opts.debugSpans === true;
490
473
  this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
491
474
  this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
492
475
  this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
476
+ this.sdkName = (_f = opts.sdkName) != null ? _f : "core";
477
+ this.prefix = `[raindrop-ai/${this.sdkName}]`;
478
+ this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
479
+ this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
493
480
  }
494
481
  isDebugEnabled() {
495
482
  return this.debug;
496
483
  }
484
+ authHeaders() {
485
+ return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
486
+ }
497
487
  startSpan(args) {
498
- var _a;
488
+ var _a, _b;
499
489
  const ids = createSpanIds(args.parent);
500
- const started = nowUnixNanoString();
490
+ const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
501
491
  const attrs = [
502
492
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
503
- // Important: omit userId to avoid backend spans->events duplication
504
493
  attrString("ai.operationId", args.operationId)
505
494
  ];
506
- if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
495
+ if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
507
496
  return { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
508
497
  }
509
498
  endSpan(span, extra) {
510
- var _a;
499
+ var _a, _b;
511
500
  if (span.endTimeUnixNano) return;
512
- span.endTimeUnixNano = nowUnixNanoString();
513
- if ((_a = extra == null ? void 0 : extra.attributes) == null ? void 0 : _a.length) {
501
+ span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
502
+ if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
514
503
  span.attributes.push(...extra.attributes);
515
504
  }
516
- let status;
517
- if ((extra == null ? void 0 : extra.error) !== void 0) {
505
+ let status = extra == null ? void 0 : extra.status;
506
+ if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
518
507
  const message = extra.error instanceof Error ? extra.error.message : String(extra.error);
519
508
  status = { code: SpanStatusCode.ERROR, message };
520
509
  }
@@ -528,12 +517,29 @@ var TraceShipper = class {
528
517
  });
529
518
  this.enqueue(otlp);
530
519
  }
520
+ createSpan(args) {
521
+ var _a;
522
+ const ids = createSpanIds(args.parent);
523
+ const attrs = [
524
+ attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
525
+ ];
526
+ if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
527
+ const otlp = buildOtlpSpan({
528
+ ids,
529
+ name: args.name,
530
+ startTimeUnixNano: args.startTimeUnixNano,
531
+ endTimeUnixNano: args.endTimeUnixNano,
532
+ attributes: attrs,
533
+ status: args.status
534
+ });
535
+ this.enqueue(otlp);
536
+ }
531
537
  enqueue(span) {
532
538
  if (!this.enabled) return;
533
539
  if (this.debugSpans) {
534
540
  const short = (s) => s ? s.slice(-8) : "none";
535
541
  console.log(
536
- `[raindrop-ai/ai-sdk][span] name=${span.name} trace=${short(span.traceId)} span=${short(span.spanId)} parent=${short(
542
+ `${this.prefix}[span] name=${span.name} trace=${short(span.traceId)} span=${short(span.spanId)} parent=${short(
537
543
  span.parentSpanId
538
544
  )}`
539
545
  );
@@ -563,30 +569,27 @@ var TraceShipper = class {
563
569
  }
564
570
  while (this.queue.length > 0) {
565
571
  const batch = this.queue.splice(0, this.maxBatchSize);
566
- const body = buildExportTraceServiceRequest(batch);
572
+ const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
567
573
  const url = `${this.baseUrl}traces`;
568
574
  if (this.debug) {
569
- console.log("[raindrop-ai/ai-sdk] sending traces batch", {
575
+ console.log(`${this.prefix} sending traces batch`, {
570
576
  spans: batch.length,
571
577
  endpoint: url
572
578
  });
573
579
  }
574
- const p = postJson(
575
- url,
576
- body,
577
- { Authorization: `Bearer ${this.writeKey}` },
578
- { maxAttempts: 3, debug: this.debug }
579
- );
580
+ const p = postJson(url, body, this.authHeaders(), {
581
+ maxAttempts: 3,
582
+ debug: this.debug,
583
+ sdkName: this.sdkName
584
+ });
580
585
  this.inFlight.add(p);
581
586
  try {
582
587
  try {
583
588
  await p;
584
- if (this.debug) console.log(`[raindrop-ai/ai-sdk] sent ${batch.length} spans`);
589
+ if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
585
590
  } catch (err) {
586
- if (this.debug) {
587
- const msg = err instanceof Error ? err.message : String(err);
588
- console.warn(`[raindrop-ai/ai-sdk] failed to send spans (dropping): ${msg}`);
589
- }
591
+ const msg = err instanceof Error ? err.message : String(err);
592
+ console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`);
590
593
  }
591
594
  } finally {
592
595
  this.inFlight.delete(p);
@@ -603,8 +606,6 @@ var TraceShipper = class {
603
606
  })));
604
607
  }
605
608
  };
606
-
607
- // src/internal/spanContext.ts
608
609
  var NOOP_SPAN = {
609
610
  traceIdB64: "",
610
611
  spanIdB64: "",
@@ -778,6 +779,41 @@ async function* asyncGeneratorWithCurrent(span, gen) {
778
779
  }
779
780
  }
780
781
 
782
+ // package.json
783
+ var package_default = {
784
+ name: "@raindrop-ai/ai-sdk",
785
+ version: "0.0.16"};
786
+
787
+ // src/internal/version.ts
788
+ var libraryName = package_default.name;
789
+ var libraryVersion = package_default.version;
790
+
791
+ // src/internal/events.ts
792
+ var EventShipper2 = class extends EventShipper {
793
+ constructor(opts) {
794
+ var _a, _b, _c;
795
+ super({
796
+ ...opts,
797
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
798
+ libraryName: (_b = opts.libraryName) != null ? _b : libraryName,
799
+ libraryVersion: (_c = opts.libraryVersion) != null ? _c : libraryVersion
800
+ });
801
+ }
802
+ };
803
+
804
+ // src/internal/traces.ts
805
+ var TraceShipper2 = class extends TraceShipper {
806
+ constructor(opts) {
807
+ var _a, _b, _c;
808
+ super({
809
+ ...opts,
810
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
811
+ serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
812
+ serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
813
+ });
814
+ }
815
+ };
816
+
781
817
  // src/internal/wrap/helpers.ts
782
818
  function isRecord(value) {
783
819
  return typeof value === "object" && value !== null;
@@ -2901,14 +2937,14 @@ function createRaindropAISDK(opts) {
2901
2937
  "[raindrop-ai/ai-sdk] writeKey not provided; telemetry shipping is disabled"
2902
2938
  );
2903
2939
  }
2904
- const eventShipper = new EventShipper({
2940
+ const eventShipper = new EventShipper2({
2905
2941
  writeKey,
2906
2942
  endpoint: opts.endpoint,
2907
2943
  enabled: eventsEnabled,
2908
2944
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
2909
2945
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
2910
2946
  });
2911
- const traceShipper = new TraceShipper({
2947
+ const traceShipper = new TraceShipper2({
2912
2948
  writeKey,
2913
2949
  endpoint: opts.endpoint,
2914
2950
  enabled: tracesEnabled,