@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.
- package/dist/{chunk-HV5PGIWQ.mjs → chunk-MYJCN2H7.mjs} +272 -236
- package/dist/index.d.mts +0 -46
- package/dist/index.d.ts +0 -46
- package/dist/index.js +272 -236
- package/dist/index.mjs +1 -1
- package/dist/index.node.js +272 -236
- package/dist/index.node.mjs +1 -1
- package/dist/index.workers.js +272 -236
- package/dist/index.workers.mjs +1 -1
- package/package.json +2 -1
|
@@ -1,4 +1,58 @@
|
|
|
1
|
-
//
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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(
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
250
|
-
|
|
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 :
|
|
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(
|
|
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(
|
|
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
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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(
|
|
448
|
+
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
326
449
|
}
|
|
327
450
|
} catch (err) {
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
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 ((
|
|
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 ((
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
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(
|
|
589
|
+
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
585
590
|
} catch (err) {
|
|
586
|
-
|
|
587
|
-
|
|
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
|
|
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
|
|
2947
|
+
const traceShipper = new TraceShipper2({
|
|
2912
2948
|
writeKey,
|
|
2913
2949
|
endpoint: opts.endpoint,
|
|
2914
2950
|
enabled: tracesEnabled,
|