@raindrop-ai/ai-sdk 0.0.33 → 0.0.35
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/README.md +22 -0
- package/dist/{chunk-FIX66Y7M.mjs → chunk-XPZBPNLC.mjs} +475 -77
- package/dist/{index-Dcf4FPZL.d.mts → index-DFLIiW1D.d.mts} +136 -2
- package/dist/{index-Dcf4FPZL.d.ts → index-DFLIiW1D.d.ts} +136 -2
- package/dist/index.browser.d.mts +136 -2
- package/dist/index.browser.d.ts +136 -2
- package/dist/index.browser.js +478 -76
- package/dist/index.browser.mjs +475 -77
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.js +478 -76
- package/dist/index.node.mjs +1 -1
- package/dist/index.workers.d.mts +1 -1
- package/dist/index.workers.d.ts +1 -1
- package/dist/index.workers.js +478 -76
- package/dist/index.workers.mjs +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
2
|
|
|
3
|
-
// ../core/dist/chunk-
|
|
3
|
+
// ../core/dist/chunk-SK6EJEO7.js
|
|
4
4
|
function getCrypto() {
|
|
5
5
|
const c = globalThis.crypto;
|
|
6
6
|
return c;
|
|
@@ -55,6 +55,8 @@ function base64Encode(bytes) {
|
|
|
55
55
|
}
|
|
56
56
|
return out;
|
|
57
57
|
}
|
|
58
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
59
|
+
var MAX_RETRY_DELAY_MS = 3e4;
|
|
58
60
|
function wait(ms) {
|
|
59
61
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
60
62
|
}
|
|
@@ -62,6 +64,46 @@ function formatEndpoint(endpoint) {
|
|
|
62
64
|
if (!endpoint) return void 0;
|
|
63
65
|
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
64
66
|
}
|
|
67
|
+
function redactUrlForLog(url) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = new URL(url);
|
|
70
|
+
parsed.username = "";
|
|
71
|
+
parsed.password = "";
|
|
72
|
+
parsed.search = "";
|
|
73
|
+
parsed.hash = "";
|
|
74
|
+
return parsed.toString();
|
|
75
|
+
} catch (e) {
|
|
76
|
+
return "<unparseable-url>";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var RATE_LIMITED_LOG_INTERVAL_MS = 3e4;
|
|
80
|
+
var rateLimitedLogLast = /* @__PURE__ */ new Map();
|
|
81
|
+
function rateLimitedLog(key, log) {
|
|
82
|
+
const now = Date.now();
|
|
83
|
+
const last = rateLimitedLogLast.get(key);
|
|
84
|
+
if (last !== void 0 && now - last < RATE_LIMITED_LOG_INTERVAL_MS) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
rateLimitedLogLast.set(key, now);
|
|
88
|
+
log();
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
async function raceWithTimeout(promise, timeoutMs) {
|
|
92
|
+
let timer;
|
|
93
|
+
const settledInTime = await Promise.race([
|
|
94
|
+
promise.then(
|
|
95
|
+
() => true,
|
|
96
|
+
() => true
|
|
97
|
+
),
|
|
98
|
+
new Promise((resolve) => {
|
|
99
|
+
var _a;
|
|
100
|
+
timer = setTimeout(() => resolve(false), Math.max(0, timeoutMs));
|
|
101
|
+
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
102
|
+
})
|
|
103
|
+
]);
|
|
104
|
+
if (timer) clearTimeout(timer);
|
|
105
|
+
return settledInTime;
|
|
106
|
+
}
|
|
65
107
|
function parseRetryAfter(headers) {
|
|
66
108
|
var _a;
|
|
67
109
|
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
@@ -78,12 +120,12 @@ function parseRetryAfter(headers) {
|
|
|
78
120
|
function getRetryDelayMs(attemptNumber, previousError) {
|
|
79
121
|
if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
|
|
80
122
|
const v = previousError.retryAfterMs;
|
|
81
|
-
if (typeof v === "number") return Math.max(0, v);
|
|
123
|
+
if (typeof v === "number") return Math.min(Math.max(0, v), MAX_RETRY_DELAY_MS);
|
|
82
124
|
}
|
|
83
125
|
if (attemptNumber <= 1) return 0;
|
|
84
126
|
const base = 500;
|
|
85
127
|
const factor = Math.pow(2, attemptNumber - 2);
|
|
86
|
-
return base * factor;
|
|
128
|
+
return Math.min(base * factor, MAX_RETRY_DELAY_MS);
|
|
87
129
|
}
|
|
88
130
|
async function withRetry(operation, opName2, opts) {
|
|
89
131
|
const prefix = opts.sdkName ? `[raindrop-ai/${opts.sdkName}]` : "[raindrop-ai/core]";
|
|
@@ -118,7 +160,9 @@ async function withRetry(operation, opName2, opts) {
|
|
|
118
160
|
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
119
161
|
}
|
|
120
162
|
async function postJson(url, body, headers, opts) {
|
|
121
|
-
|
|
163
|
+
var _a;
|
|
164
|
+
const opName2 = `POST ${redactUrlForLog(url)}`;
|
|
165
|
+
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
122
166
|
await withRetry(
|
|
123
167
|
async () => {
|
|
124
168
|
const resp = await fetch(url, {
|
|
@@ -127,7 +171,8 @@ async function postJson(url, body, headers, opts) {
|
|
|
127
171
|
"Content-Type": "application/json",
|
|
128
172
|
...headers
|
|
129
173
|
},
|
|
130
|
-
body: JSON.stringify(body)
|
|
174
|
+
body: JSON.stringify(body),
|
|
175
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
131
176
|
});
|
|
132
177
|
if (!resp.ok) {
|
|
133
178
|
const text = await resp.text().catch(() => "");
|
|
@@ -144,6 +189,27 @@ async function postJson(url, body, headers, opts) {
|
|
|
144
189
|
opts
|
|
145
190
|
);
|
|
146
191
|
}
|
|
192
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS = 1e6;
|
|
193
|
+
var TRUNCATION_MARKER = "...[truncated by raindrop]";
|
|
194
|
+
var currentDefaultMaxTextFieldChars = DEFAULT_MAX_TEXT_FIELD_CHARS;
|
|
195
|
+
function resolveMaxTextFieldChars(value) {
|
|
196
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
197
|
+
return Math.floor(value);
|
|
198
|
+
}
|
|
199
|
+
return currentDefaultMaxTextFieldChars;
|
|
200
|
+
}
|
|
201
|
+
function truncateToLimit(text, limit) {
|
|
202
|
+
if (limit > TRUNCATION_MARKER.length) {
|
|
203
|
+
return text.slice(0, limit - TRUNCATION_MARKER.length) + TRUNCATION_MARKER;
|
|
204
|
+
}
|
|
205
|
+
return text.slice(0, Math.max(0, limit));
|
|
206
|
+
}
|
|
207
|
+
function capText(value, limit) {
|
|
208
|
+
if (typeof value !== "string") return value;
|
|
209
|
+
const max = limit != null ? limit : currentDefaultMaxTextFieldChars;
|
|
210
|
+
if (value.length <= max) return value;
|
|
211
|
+
return truncateToLimit(value, max);
|
|
212
|
+
}
|
|
147
213
|
var SpanStatusCode = {
|
|
148
214
|
UNSET: 0,
|
|
149
215
|
ERROR: 2
|
|
@@ -331,6 +397,27 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
|
331
397
|
).catch(() => {
|
|
332
398
|
});
|
|
333
399
|
}
|
|
400
|
+
var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
|
|
401
|
+
var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
402
|
+
function isValidProjectIdSlug(value) {
|
|
403
|
+
return PROJECT_ID_SLUG_PATTERN.test(value);
|
|
404
|
+
}
|
|
405
|
+
function normalizeProjectId(raw, opts) {
|
|
406
|
+
if (typeof raw !== "string") return void 0;
|
|
407
|
+
const trimmed = raw.trim();
|
|
408
|
+
if (!trimmed) return void 0;
|
|
409
|
+
if (!isValidProjectIdSlug(trimmed) && opts.debug) {
|
|
410
|
+
console.warn(
|
|
411
|
+
`${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
return trimmed;
|
|
415
|
+
}
|
|
416
|
+
function projectIdHeaders(projectId) {
|
|
417
|
+
return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
|
|
418
|
+
}
|
|
419
|
+
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
420
|
+
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
334
421
|
function mergePatches(target, source) {
|
|
335
422
|
var _a, _b, _c, _d;
|
|
336
423
|
const out = { ...target, ...source };
|
|
@@ -348,6 +435,7 @@ var EventShipper = class {
|
|
|
348
435
|
this.sticky = /* @__PURE__ */ new Map();
|
|
349
436
|
this.timers = /* @__PURE__ */ new Map();
|
|
350
437
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
438
|
+
this.hasShutdown = false;
|
|
351
439
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
352
440
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
353
441
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -357,10 +445,15 @@ var EventShipper = class {
|
|
|
357
445
|
this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
|
|
358
446
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
359
447
|
this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
|
|
448
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
360
449
|
this.localDebuggerUrl = (_f = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _f : void 0;
|
|
361
450
|
if (this.debug && this.localDebuggerUrl) {
|
|
362
451
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
363
452
|
}
|
|
453
|
+
this.projectId = normalizeProjectId(opts.projectId, {
|
|
454
|
+
debug: this.debug,
|
|
455
|
+
prefix: this.prefix
|
|
456
|
+
});
|
|
364
457
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
365
458
|
this.context = {
|
|
366
459
|
library: {
|
|
@@ -379,10 +472,55 @@ var EventShipper = class {
|
|
|
379
472
|
authHeaders() {
|
|
380
473
|
return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
|
|
381
474
|
}
|
|
475
|
+
requestHeaders() {
|
|
476
|
+
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
480
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
481
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
482
|
+
* of issuing a request that could outlive process exit.
|
|
483
|
+
*
|
|
484
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
485
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
486
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
487
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
488
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
489
|
+
* run as a single short attempt rather than regaining the full retry
|
|
490
|
+
* schedule.
|
|
491
|
+
*/
|
|
492
|
+
requestOpts() {
|
|
493
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
494
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
495
|
+
if (remainingMs <= 0) return null;
|
|
496
|
+
return {
|
|
497
|
+
maxAttempts: 1,
|
|
498
|
+
debug: this.debug,
|
|
499
|
+
sdkName: this.sdkName,
|
|
500
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
if (this.hasShutdown) {
|
|
504
|
+
return {
|
|
505
|
+
maxAttempts: 1,
|
|
506
|
+
debug: this.debug,
|
|
507
|
+
sdkName: this.sdkName,
|
|
508
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
512
|
+
}
|
|
382
513
|
async patch(eventId, patch) {
|
|
383
514
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
384
515
|
if (!this.enabled) return;
|
|
385
516
|
if (!eventId || !eventId.trim()) return;
|
|
517
|
+
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
518
|
+
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
519
|
+
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
520
|
+
}
|
|
521
|
+
if (typeof patch.output === "string" && patch.output.length > maxChars) {
|
|
522
|
+
patch = { ...patch, output: capText(patch.output, maxChars) };
|
|
523
|
+
}
|
|
386
524
|
if (this.debug) {
|
|
387
525
|
console.log(`${this.prefix} queue patch`, {
|
|
388
526
|
eventId,
|
|
@@ -429,9 +567,16 @@ var EventShipper = class {
|
|
|
429
567
|
})));
|
|
430
568
|
}
|
|
431
569
|
async shutdown() {
|
|
432
|
-
|
|
433
|
-
this.
|
|
434
|
-
|
|
570
|
+
this.hasShutdown = true;
|
|
571
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
572
|
+
try {
|
|
573
|
+
for (const t of this.timers.values()) clearTimeout(t);
|
|
574
|
+
this.timers.clear();
|
|
575
|
+
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
576
|
+
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
577
|
+
} finally {
|
|
578
|
+
this.shutdownDeadlineAt = void 0;
|
|
579
|
+
}
|
|
435
580
|
}
|
|
436
581
|
async trackSignal(signal) {
|
|
437
582
|
var _a, _b;
|
|
@@ -453,15 +598,19 @@ var EventShipper = class {
|
|
|
453
598
|
];
|
|
454
599
|
if (!this.writeKey) return;
|
|
455
600
|
const url = `${this.baseUrl}signals/track`;
|
|
601
|
+
const opts = this.requestOpts();
|
|
602
|
+
if (!opts) {
|
|
603
|
+
this.warnShutdownDrop("signal");
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
456
606
|
try {
|
|
457
|
-
await postJson(url, body, this.
|
|
458
|
-
maxAttempts: 3,
|
|
459
|
-
debug: this.debug,
|
|
460
|
-
sdkName: this.sdkName
|
|
461
|
-
});
|
|
607
|
+
await postJson(url, body, this.requestHeaders(), opts);
|
|
462
608
|
} catch (err) {
|
|
463
609
|
const msg = err instanceof Error ? err.message : String(err);
|
|
464
|
-
|
|
610
|
+
rateLimitedLog(
|
|
611
|
+
`${this.prefix}.send_signal_failed`,
|
|
612
|
+
() => console.warn(`${this.prefix} failed to send signal (dropping): ${msg}`)
|
|
613
|
+
);
|
|
465
614
|
}
|
|
466
615
|
}
|
|
467
616
|
async identify(users) {
|
|
@@ -485,17 +634,27 @@ var EventShipper = class {
|
|
|
485
634
|
if (!this.writeKey) return;
|
|
486
635
|
if (body.length === 0) return;
|
|
487
636
|
const url = `${this.baseUrl}users/identify`;
|
|
637
|
+
const opts = this.requestOpts();
|
|
638
|
+
if (!opts) {
|
|
639
|
+
this.warnShutdownDrop("identify");
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
488
642
|
try {
|
|
489
|
-
await postJson(url, body, this.
|
|
490
|
-
maxAttempts: 3,
|
|
491
|
-
debug: this.debug,
|
|
492
|
-
sdkName: this.sdkName
|
|
493
|
-
});
|
|
643
|
+
await postJson(url, body, this.requestHeaders(), opts);
|
|
494
644
|
} catch (err) {
|
|
495
645
|
const msg = err instanceof Error ? err.message : String(err);
|
|
496
|
-
|
|
646
|
+
rateLimitedLog(
|
|
647
|
+
`${this.prefix}.send_identify_failed`,
|
|
648
|
+
() => console.warn(`${this.prefix} failed to send identify (dropping): ${msg}`)
|
|
649
|
+
);
|
|
497
650
|
}
|
|
498
651
|
}
|
|
652
|
+
warnShutdownDrop(what) {
|
|
653
|
+
rateLimitedLog(
|
|
654
|
+
`${this.prefix}.shutdown_deadline`,
|
|
655
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; dropping ${what}`)
|
|
656
|
+
);
|
|
657
|
+
}
|
|
499
658
|
async flushOne(eventId) {
|
|
500
659
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
501
660
|
if (!this.enabled) return;
|
|
@@ -571,11 +730,13 @@ var EventShipper = class {
|
|
|
571
730
|
if (!isPending) this.sticky.delete(eventId);
|
|
572
731
|
return;
|
|
573
732
|
}
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
733
|
+
const opts = this.requestOpts();
|
|
734
|
+
if (!opts) {
|
|
735
|
+
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
736
|
+
if (!isPending) this.sticky.delete(eventId);
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
579
740
|
this.inFlight.add(p);
|
|
580
741
|
try {
|
|
581
742
|
try {
|
|
@@ -585,7 +746,10 @@ var EventShipper = class {
|
|
|
585
746
|
}
|
|
586
747
|
} catch (err) {
|
|
587
748
|
const msg = err instanceof Error ? err.message : String(err);
|
|
588
|
-
|
|
749
|
+
rateLimitedLog(
|
|
750
|
+
`${this.prefix}.send_track_partial_failed`,
|
|
751
|
+
() => console.warn(`${this.prefix} failed to send track_partial (dropping): ${msg}`)
|
|
752
|
+
);
|
|
589
753
|
}
|
|
590
754
|
} finally {
|
|
591
755
|
this.inFlight.delete(p);
|
|
@@ -684,10 +848,24 @@ function redactJsonAttributeValue(key, value) {
|
|
|
684
848
|
if (scrubbedJson === json) return void 0;
|
|
685
849
|
return { stringValue: scrubbedJson };
|
|
686
850
|
}
|
|
851
|
+
function applyOtelSpanAttributeLimit(limit) {
|
|
852
|
+
var _a, _b;
|
|
853
|
+
try {
|
|
854
|
+
const raw = (_b = (_a = globalThis == null ? void 0 : globalThis.process) == null ? void 0 : _a.env) == null ? void 0 : _b.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
855
|
+
if (!raw) return limit;
|
|
856
|
+
const parsed = Number.parseInt(raw, 10);
|
|
857
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
858
|
+
return Math.min(limit, parsed);
|
|
859
|
+
}
|
|
860
|
+
} catch (e) {
|
|
861
|
+
}
|
|
862
|
+
return limit;
|
|
863
|
+
}
|
|
687
864
|
var TraceShipper = class {
|
|
688
865
|
constructor(opts) {
|
|
689
866
|
this.queue = [];
|
|
690
867
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
868
|
+
this.hasShutdown = false;
|
|
691
869
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
692
870
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
693
871
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -705,8 +883,45 @@ var TraceShipper = class {
|
|
|
705
883
|
if (this.debug && this.localDebuggerUrl) {
|
|
706
884
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
707
885
|
}
|
|
886
|
+
this.projectId = normalizeProjectId(opts.projectId, {
|
|
887
|
+
debug: this.debug,
|
|
888
|
+
prefix: this.prefix
|
|
889
|
+
});
|
|
708
890
|
this.transformSpanHook = opts.transformSpan;
|
|
709
891
|
this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
|
|
892
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
896
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
897
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
898
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
899
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
900
|
+
* in the surviving prefix).
|
|
901
|
+
*
|
|
902
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
903
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
904
|
+
*/
|
|
905
|
+
capSpanAttributes(span) {
|
|
906
|
+
var _a;
|
|
907
|
+
const maxChars = applyOtelSpanAttributeLimit(
|
|
908
|
+
resolveMaxTextFieldChars(this.maxTextFieldCharsOpt)
|
|
909
|
+
);
|
|
910
|
+
const attrs = span.attributes;
|
|
911
|
+
if (!attrs || attrs.length === 0) return span;
|
|
912
|
+
let nextAttrs;
|
|
913
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
914
|
+
const attr = attrs[i];
|
|
915
|
+
const value = (_a = attr.value) == null ? void 0 : _a.stringValue;
|
|
916
|
+
if (typeof value !== "string" || value.length <= maxChars) continue;
|
|
917
|
+
if (!nextAttrs) nextAttrs = attrs.slice();
|
|
918
|
+
nextAttrs[i] = {
|
|
919
|
+
key: attr.key,
|
|
920
|
+
value: { ...attr.value, stringValue: capText(value, maxChars) }
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
if (!nextAttrs) return span;
|
|
924
|
+
return { ...span, attributes: nextAttrs };
|
|
710
925
|
}
|
|
711
926
|
/**
|
|
712
927
|
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
@@ -740,7 +955,7 @@ var TraceShipper = class {
|
|
|
740
955
|
if (!this.disableDefaultRedaction) {
|
|
741
956
|
current = defaultTransformSpan(current);
|
|
742
957
|
}
|
|
743
|
-
return current;
|
|
958
|
+
return this.capSpanAttributes(current);
|
|
744
959
|
}
|
|
745
960
|
isDebugEnabled() {
|
|
746
961
|
return this.debug;
|
|
@@ -748,6 +963,9 @@ var TraceShipper = class {
|
|
|
748
963
|
authHeaders() {
|
|
749
964
|
return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
|
|
750
965
|
}
|
|
966
|
+
requestHeaders() {
|
|
967
|
+
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
968
|
+
}
|
|
751
969
|
startSpan(args) {
|
|
752
970
|
var _a, _b;
|
|
753
971
|
const ids = createSpanIds(args.parent);
|
|
@@ -861,6 +1079,16 @@ var TraceShipper = class {
|
|
|
861
1079
|
while (this.queue.length > 0) {
|
|
862
1080
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
863
1081
|
if (!this.writeKey) continue;
|
|
1082
|
+
const opts = this.requestOpts();
|
|
1083
|
+
if (!opts) {
|
|
1084
|
+
rateLimitedLog(
|
|
1085
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1086
|
+
() => console.warn(
|
|
1087
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1088
|
+
)
|
|
1089
|
+
);
|
|
1090
|
+
continue;
|
|
1091
|
+
}
|
|
864
1092
|
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
865
1093
|
const url = `${this.baseUrl}traces`;
|
|
866
1094
|
if (this.debug) {
|
|
@@ -869,11 +1097,7 @@ var TraceShipper = class {
|
|
|
869
1097
|
endpoint: url
|
|
870
1098
|
});
|
|
871
1099
|
}
|
|
872
|
-
const p = postJson(url, body, this.
|
|
873
|
-
maxAttempts: 3,
|
|
874
|
-
debug: this.debug,
|
|
875
|
-
sdkName: this.sdkName
|
|
876
|
-
});
|
|
1100
|
+
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
877
1101
|
this.inFlight.add(p);
|
|
878
1102
|
try {
|
|
879
1103
|
try {
|
|
@@ -881,21 +1105,61 @@ var TraceShipper = class {
|
|
|
881
1105
|
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
882
1106
|
} catch (err) {
|
|
883
1107
|
const msg = err instanceof Error ? err.message : String(err);
|
|
884
|
-
|
|
1108
|
+
rateLimitedLog(
|
|
1109
|
+
`${this.prefix}.send_spans_failed`,
|
|
1110
|
+
() => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
|
|
1111
|
+
);
|
|
885
1112
|
}
|
|
886
1113
|
} finally {
|
|
887
1114
|
this.inFlight.delete(p);
|
|
888
1115
|
}
|
|
889
1116
|
}
|
|
890
1117
|
}
|
|
1118
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
1119
|
+
requestOpts() {
|
|
1120
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
1121
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
1122
|
+
if (remainingMs <= 0) return null;
|
|
1123
|
+
return {
|
|
1124
|
+
maxAttempts: 1,
|
|
1125
|
+
debug: this.debug,
|
|
1126
|
+
sdkName: this.sdkName,
|
|
1127
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
if (this.hasShutdown) {
|
|
1131
|
+
return {
|
|
1132
|
+
maxAttempts: 1,
|
|
1133
|
+
debug: this.debug,
|
|
1134
|
+
sdkName: this.sdkName,
|
|
1135
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
1139
|
+
}
|
|
891
1140
|
async shutdown() {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1141
|
+
this.hasShutdown = true;
|
|
1142
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
1143
|
+
try {
|
|
1144
|
+
if (this.timer) {
|
|
1145
|
+
clearTimeout(this.timer);
|
|
1146
|
+
this.timer = void 0;
|
|
1147
|
+
}
|
|
1148
|
+
const drain = async () => {
|
|
1149
|
+
await this.flush();
|
|
1150
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1151
|
+
})));
|
|
1152
|
+
};
|
|
1153
|
+
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
1154
|
+
if (!settled) {
|
|
1155
|
+
rateLimitedLog(
|
|
1156
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1157
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
} finally {
|
|
1161
|
+
this.shutdownDeadlineAt = void 0;
|
|
895
1162
|
}
|
|
896
|
-
await this.flush();
|
|
897
|
-
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
898
|
-
})));
|
|
899
1163
|
}
|
|
900
1164
|
};
|
|
901
1165
|
var NOOP_SPAN = {
|
|
@@ -1017,6 +1281,133 @@ async function* asyncGeneratorWithCurrent(span, gen) {
|
|
|
1017
1281
|
}
|
|
1018
1282
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1019
1283
|
|
|
1284
|
+
// src/internal/truncation.ts
|
|
1285
|
+
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
1286
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
|
|
1287
|
+
var MAX_DEPTH = 12;
|
|
1288
|
+
var configuredMaxTextFieldChars;
|
|
1289
|
+
function setMaxTextFieldChars(limit) {
|
|
1290
|
+
if (limit === void 0) return;
|
|
1291
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
1292
|
+
configuredMaxTextFieldChars = Math.floor(limit);
|
|
1293
|
+
} else {
|
|
1294
|
+
console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
function otelEnvLimit() {
|
|
1298
|
+
var _a;
|
|
1299
|
+
if (typeof process === "undefined") return void 0;
|
|
1300
|
+
const raw = (_a = process.env) == null ? void 0 : _a.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
1301
|
+
if (!raw) return void 0;
|
|
1302
|
+
const parsed = Number.parseInt(raw, 10);
|
|
1303
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1304
|
+
}
|
|
1305
|
+
function effectiveMaxTextFieldChars() {
|
|
1306
|
+
const base = configuredMaxTextFieldChars != null ? configuredMaxTextFieldChars : DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
1307
|
+
const env = otelEnvLimit();
|
|
1308
|
+
return env !== void 0 && env < base ? env : base;
|
|
1309
|
+
}
|
|
1310
|
+
function truncateToLimit2(text, limit) {
|
|
1311
|
+
if (limit > TRUNCATION_MARKER2.length) {
|
|
1312
|
+
return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
|
|
1313
|
+
}
|
|
1314
|
+
return text.slice(0, limit);
|
|
1315
|
+
}
|
|
1316
|
+
function capText2(value, limit) {
|
|
1317
|
+
if (typeof value !== "string") return value;
|
|
1318
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1319
|
+
if (value.length <= max) return value;
|
|
1320
|
+
return truncateToLimit2(value, max);
|
|
1321
|
+
}
|
|
1322
|
+
function boundedClone2(value, budget, depth) {
|
|
1323
|
+
var _a, _b;
|
|
1324
|
+
if (budget.remaining <= 0) return TRUNCATION_MARKER2;
|
|
1325
|
+
if (typeof value === "string") {
|
|
1326
|
+
if (value.length > budget.remaining) {
|
|
1327
|
+
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1328
|
+
budget.remaining = 0;
|
|
1329
|
+
return taken;
|
|
1330
|
+
}
|
|
1331
|
+
budget.remaining -= Math.max(value.length, 1);
|
|
1332
|
+
return value;
|
|
1333
|
+
}
|
|
1334
|
+
if (value === null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1335
|
+
budget.remaining -= 8;
|
|
1336
|
+
return value;
|
|
1337
|
+
}
|
|
1338
|
+
if (typeof value !== "object") {
|
|
1339
|
+
budget.remaining -= 1;
|
|
1340
|
+
return value;
|
|
1341
|
+
}
|
|
1342
|
+
if (value instanceof Uint8Array) {
|
|
1343
|
+
const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
|
|
1344
|
+
if (value.byteLength > maxBytes) {
|
|
1345
|
+
const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
|
|
1346
|
+
budget.remaining = 0;
|
|
1347
|
+
return taken;
|
|
1348
|
+
}
|
|
1349
|
+
const encoded = base64Encode(value);
|
|
1350
|
+
budget.remaining -= Math.max(encoded.length, 1);
|
|
1351
|
+
return encoded;
|
|
1352
|
+
}
|
|
1353
|
+
if (depth >= MAX_DEPTH) {
|
|
1354
|
+
budget.remaining -= 16;
|
|
1355
|
+
const name = (_b = (_a = value.constructor) == null ? void 0 : _a.name) != null ? _b : "object";
|
|
1356
|
+
return `<max depth: ${name}>`;
|
|
1357
|
+
}
|
|
1358
|
+
const toJSON = value.toJSON;
|
|
1359
|
+
if (typeof toJSON === "function") {
|
|
1360
|
+
budget.remaining -= 2;
|
|
1361
|
+
return boundedClone2(toJSON.call(value), budget, depth + 1);
|
|
1362
|
+
}
|
|
1363
|
+
if (Array.isArray(value)) {
|
|
1364
|
+
budget.remaining -= 2;
|
|
1365
|
+
const out2 = [];
|
|
1366
|
+
for (const item of value) {
|
|
1367
|
+
if (budget.remaining <= 0) {
|
|
1368
|
+
out2.push(TRUNCATION_MARKER2);
|
|
1369
|
+
break;
|
|
1370
|
+
}
|
|
1371
|
+
out2.push(boundedClone2(item, budget, depth + 1));
|
|
1372
|
+
}
|
|
1373
|
+
return out2;
|
|
1374
|
+
}
|
|
1375
|
+
budget.remaining -= 2;
|
|
1376
|
+
const out = {};
|
|
1377
|
+
for (const key in value) {
|
|
1378
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
1379
|
+
if (budget.remaining <= 0) {
|
|
1380
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
1381
|
+
break;
|
|
1382
|
+
}
|
|
1383
|
+
let cappedKey = key;
|
|
1384
|
+
if (key.length > budget.remaining) {
|
|
1385
|
+
cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1386
|
+
budget.remaining = 0;
|
|
1387
|
+
out[cappedKey] = TRUNCATION_MARKER2;
|
|
1388
|
+
break;
|
|
1389
|
+
}
|
|
1390
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
1391
|
+
out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
|
|
1392
|
+
}
|
|
1393
|
+
return out;
|
|
1394
|
+
}
|
|
1395
|
+
function boundedStringify(value, limit) {
|
|
1396
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1397
|
+
try {
|
|
1398
|
+
if (typeof value === "string") {
|
|
1399
|
+
const text2 = JSON.stringify(capText2(value, max));
|
|
1400
|
+
return text2.length <= max ? text2 : truncateToLimit2(text2, max);
|
|
1401
|
+
}
|
|
1402
|
+
const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
1403
|
+
const text = JSON.stringify(pruned);
|
|
1404
|
+
if (text === void 0) return void 0;
|
|
1405
|
+
return text.length <= max ? text : truncateToLimit2(text, max);
|
|
1406
|
+
} catch (e) {
|
|
1407
|
+
return void 0;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1020
1411
|
// src/internal/wrap/helpers.ts
|
|
1021
1412
|
function isRecord(value) {
|
|
1022
1413
|
return typeof value === "object" && value !== null;
|
|
@@ -1041,21 +1432,10 @@ function isModuleNamespace(obj) {
|
|
|
1041
1432
|
}
|
|
1042
1433
|
}
|
|
1043
1434
|
function safeJson(value) {
|
|
1044
|
-
|
|
1045
|
-
return JSON.stringify(value);
|
|
1046
|
-
} catch (e) {
|
|
1047
|
-
return void 0;
|
|
1048
|
-
}
|
|
1435
|
+
return boundedStringify(value);
|
|
1049
1436
|
}
|
|
1050
1437
|
function safeJsonWithUint8(value) {
|
|
1051
|
-
|
|
1052
|
-
return JSON.stringify(value, (_key, v) => {
|
|
1053
|
-
if (v instanceof Uint8Array) return base64Encode(v);
|
|
1054
|
-
return v;
|
|
1055
|
-
});
|
|
1056
|
-
} catch (e) {
|
|
1057
|
-
return void 0;
|
|
1058
|
-
}
|
|
1438
|
+
return boundedStringify(value);
|
|
1059
1439
|
}
|
|
1060
1440
|
function extractModelInfo(model) {
|
|
1061
1441
|
if (typeof model === "string") {
|
|
@@ -1951,7 +2331,10 @@ var RaindropTelemetryIntegration = class {
|
|
|
1951
2331
|
inputAttrs.push(
|
|
1952
2332
|
attrStringArray(
|
|
1953
2333
|
"ai.prompt.tools",
|
|
1954
|
-
event.stepTools.map((t) =>
|
|
2334
|
+
event.stepTools.map((t) => {
|
|
2335
|
+
var _a;
|
|
2336
|
+
return (_a = safeJsonWithUint8(t)) != null ? _a : "";
|
|
2337
|
+
})
|
|
1955
2338
|
)
|
|
1956
2339
|
);
|
|
1957
2340
|
}
|
|
@@ -1959,7 +2342,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
1959
2342
|
inputAttrs.push(
|
|
1960
2343
|
attrString(
|
|
1961
2344
|
"ai.prompt.toolChoice",
|
|
1962
|
-
|
|
2345
|
+
safeJsonWithUint8(event.stepToolChoice)
|
|
1963
2346
|
)
|
|
1964
2347
|
);
|
|
1965
2348
|
}
|
|
@@ -2015,7 +2398,9 @@ var RaindropTelemetryIntegration = class {
|
|
|
2015
2398
|
if (chunk.type === "text-delta") {
|
|
2016
2399
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
2017
2400
|
if (typeof delta === "string") {
|
|
2018
|
-
state.accumulatedText
|
|
2401
|
+
if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
|
|
2402
|
+
state.accumulatedText += delta;
|
|
2403
|
+
}
|
|
2019
2404
|
this.emitLive(state, "text_delta", delta);
|
|
2020
2405
|
}
|
|
2021
2406
|
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
@@ -2034,7 +2419,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2034
2419
|
if (state.recordOutputs) {
|
|
2035
2420
|
outputAttrs.push(
|
|
2036
2421
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2037
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2422
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2038
2423
|
attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
|
|
2039
2424
|
attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
|
|
2040
2425
|
attrString(
|
|
@@ -2050,7 +2435,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2050
2435
|
outputAttrs.push(
|
|
2051
2436
|
attrString(
|
|
2052
2437
|
"ai.response.toolCalls",
|
|
2053
|
-
|
|
2438
|
+
safeJsonWithUint8(
|
|
2054
2439
|
event.toolCalls.map((tc) => ({
|
|
2055
2440
|
toolCallId: tc.toolCallId,
|
|
2056
2441
|
toolName: tc.toolName,
|
|
@@ -2063,7 +2448,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2063
2448
|
if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
|
|
2064
2449
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2065
2450
|
if (reasoningText) {
|
|
2066
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2451
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2067
2452
|
}
|
|
2068
2453
|
}
|
|
2069
2454
|
}
|
|
@@ -2485,7 +2870,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2485
2870
|
if (state.recordOutputs) {
|
|
2486
2871
|
outputAttrs.push(
|
|
2487
2872
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2488
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2873
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2489
2874
|
attrString(
|
|
2490
2875
|
"ai.response.providerMetadata",
|
|
2491
2876
|
event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
|
|
@@ -2495,7 +2880,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2495
2880
|
outputAttrs.push(
|
|
2496
2881
|
attrString(
|
|
2497
2882
|
"ai.response.toolCalls",
|
|
2498
|
-
|
|
2883
|
+
safeJsonWithUint8(
|
|
2499
2884
|
event.toolCalls.map((tc) => ({
|
|
2500
2885
|
toolCallId: tc.toolCallId,
|
|
2501
2886
|
toolName: tc.toolName,
|
|
@@ -2508,7 +2893,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2508
2893
|
if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
|
|
2509
2894
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2510
2895
|
if (reasoningText) {
|
|
2511
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2896
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2512
2897
|
}
|
|
2513
2898
|
}
|
|
2514
2899
|
}
|
|
@@ -2546,7 +2931,8 @@ var RaindropTelemetryIntegration = class {
|
|
|
2546
2931
|
const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
|
|
2547
2932
|
if (!userId) return;
|
|
2548
2933
|
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
|
|
2549
|
-
const
|
|
2934
|
+
const cappedOutput = capText2(output);
|
|
2935
|
+
const input = capText2(state.inputText);
|
|
2550
2936
|
const properties = {
|
|
2551
2937
|
...(_f = this.defaultContext) == null ? void 0 : _f.properties,
|
|
2552
2938
|
...callMeta.properties
|
|
@@ -2557,7 +2943,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2557
2943
|
userId,
|
|
2558
2944
|
convoId,
|
|
2559
2945
|
input,
|
|
2560
|
-
output,
|
|
2946
|
+
output: cappedOutput,
|
|
2561
2947
|
model,
|
|
2562
2948
|
properties: Object.keys(properties).length > 0 ? properties : void 0,
|
|
2563
2949
|
isPending: false
|
|
@@ -3017,13 +3403,14 @@ function shouldKeepEventPending(params) {
|
|
|
3017
3403
|
return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
|
|
3018
3404
|
}
|
|
3019
3405
|
function normalizePromptAttr(arg) {
|
|
3406
|
+
var _a, _b;
|
|
3020
3407
|
if (!isRecord(arg)) return arg;
|
|
3021
3408
|
const system = arg["system"];
|
|
3022
3409
|
const prompt = arg["prompt"];
|
|
3023
3410
|
const messages = arg["messages"];
|
|
3024
3411
|
if (Array.isArray(messages)) {
|
|
3025
3412
|
if (system) {
|
|
3026
|
-
const sysContent = typeof system === "string" ? system :
|
|
3413
|
+
const sysContent = typeof system === "string" ? system : (_a = safeJsonWithUint8(system)) != null ? _a : String(system);
|
|
3027
3414
|
return [{ role: "system", content: sysContent }, ...messages];
|
|
3028
3415
|
}
|
|
3029
3416
|
return messages;
|
|
@@ -3031,7 +3418,10 @@ function normalizePromptAttr(arg) {
|
|
|
3031
3418
|
if (typeof prompt === "string") {
|
|
3032
3419
|
const msgs = [];
|
|
3033
3420
|
if (system) {
|
|
3034
|
-
msgs.push({
|
|
3421
|
+
msgs.push({
|
|
3422
|
+
role: "system",
|
|
3423
|
+
content: typeof system === "string" ? system : (_b = safeJsonWithUint8(system)) != null ? _b : String(system)
|
|
3424
|
+
});
|
|
3035
3425
|
}
|
|
3036
3426
|
msgs.push({ role: "user", content: prompt });
|
|
3037
3427
|
return msgs;
|
|
@@ -3200,7 +3590,8 @@ function createFinalize(params) {
|
|
|
3200
3590
|
};
|
|
3201
3591
|
const built = await maybeBuildEvent(options.buildEvent, allMessages);
|
|
3202
3592
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3203
|
-
const output = patch.output;
|
|
3593
|
+
const output = capText2(patch.output);
|
|
3594
|
+
const input = capText2(patch.input);
|
|
3204
3595
|
const finalModel = (_c = patch.model) != null ? _c : model;
|
|
3205
3596
|
if (setup.rootSpan) {
|
|
3206
3597
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3244,7 +3635,7 @@ function createFinalize(params) {
|
|
|
3244
3635
|
eventName: patch.eventName,
|
|
3245
3636
|
userId: setup.ctx.userId,
|
|
3246
3637
|
convoId: setup.ctx.convoId,
|
|
3247
|
-
input
|
|
3638
|
+
input,
|
|
3248
3639
|
output,
|
|
3249
3640
|
model: finalModel,
|
|
3250
3641
|
properties: patch.properties,
|
|
@@ -3759,7 +4150,8 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3759
4150
|
};
|
|
3760
4151
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
3761
4152
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3762
|
-
const output = patch.output;
|
|
4153
|
+
const output = capText2(patch.output);
|
|
4154
|
+
const input = capText2(patch.input);
|
|
3763
4155
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
3764
4156
|
if (rootSpan) {
|
|
3765
4157
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3817,7 +4209,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3817
4209
|
eventName: patch.eventName,
|
|
3818
4210
|
userId: ctx.userId,
|
|
3819
4211
|
convoId: ctx.convoId,
|
|
3820
|
-
input
|
|
4212
|
+
input,
|
|
3821
4213
|
output,
|
|
3822
4214
|
model: finalModel,
|
|
3823
4215
|
properties: patch.properties,
|
|
@@ -3966,7 +4358,8 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
3966
4358
|
};
|
|
3967
4359
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
3968
4360
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3969
|
-
const output = patch.output;
|
|
4361
|
+
const output = capText2(patch.output);
|
|
4362
|
+
const input = capText2(patch.input);
|
|
3970
4363
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
3971
4364
|
if (rootSpan) {
|
|
3972
4365
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -4024,7 +4417,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4024
4417
|
eventName: patch.eventName,
|
|
4025
4418
|
userId: ctx.userId,
|
|
4026
4419
|
convoId: ctx.convoId,
|
|
4027
|
-
input
|
|
4420
|
+
input,
|
|
4028
4421
|
output,
|
|
4029
4422
|
model: finalModel,
|
|
4030
4423
|
properties: patch.properties,
|
|
@@ -4364,7 +4757,7 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4364
4757
|
attributes: [
|
|
4365
4758
|
...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
|
|
4366
4759
|
attrString("ai.response.finishReason", finishReason),
|
|
4367
|
-
attrString("ai.response.text", activeText.length ? activeText : void 0),
|
|
4760
|
+
attrString("ai.response.text", activeText.length ? capText2(activeText) : void 0),
|
|
4368
4761
|
attrString(
|
|
4369
4762
|
"ai.response.toolCalls",
|
|
4370
4763
|
safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
|
|
@@ -4417,7 +4810,9 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4417
4810
|
} else if (typeof value["textDelta"] === "string") {
|
|
4418
4811
|
textDelta = value["textDelta"];
|
|
4419
4812
|
}
|
|
4420
|
-
if (typeof textDelta === "string"
|
|
4813
|
+
if (typeof textDelta === "string" && activeText.length <= effectiveMaxTextFieldChars()) {
|
|
4814
|
+
activeText += textDelta;
|
|
4815
|
+
}
|
|
4421
4816
|
}
|
|
4422
4817
|
if (type === "finish") finishReason = extractFinishReason(value);
|
|
4423
4818
|
if (type === "tool-call") toolCallsLocal.push(value);
|
|
@@ -4652,7 +5047,7 @@ function extractNestedTokens(usage, key) {
|
|
|
4652
5047
|
// package.json
|
|
4653
5048
|
var package_default = {
|
|
4654
5049
|
name: "@raindrop-ai/ai-sdk",
|
|
4655
|
-
version: "0.0.
|
|
5050
|
+
version: "0.0.35"};
|
|
4656
5051
|
|
|
4657
5052
|
// src/internal/version.ts
|
|
4658
5053
|
var libraryName = package_default.name;
|
|
@@ -4725,8 +5120,8 @@ function eventMetadataFromChatRequest(options) {
|
|
|
4725
5120
|
});
|
|
4726
5121
|
}
|
|
4727
5122
|
function stringify(v) {
|
|
4728
|
-
if (typeof v === "string") return v;
|
|
4729
|
-
return
|
|
5123
|
+
if (typeof v === "string") return capText2(v);
|
|
5124
|
+
return boundedStringify(v);
|
|
4730
5125
|
}
|
|
4731
5126
|
function userAttrsToOtlp(attrs) {
|
|
4732
5127
|
if (!attrs) return [];
|
|
@@ -4744,6 +5139,7 @@ function createRaindropAISDK(opts) {
|
|
|
4744
5139
|
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
4745
5140
|
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
4746
5141
|
const envDebug = envDebugEnabled();
|
|
5142
|
+
setMaxTextFieldChars(opts.maxTextFieldChars);
|
|
4747
5143
|
const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
|
|
4748
5144
|
const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
|
|
4749
5145
|
const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
|
|
@@ -4761,6 +5157,7 @@ function createRaindropAISDK(opts) {
|
|
|
4761
5157
|
enabled: eventsEnabled,
|
|
4762
5158
|
debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
|
|
4763
5159
|
partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
|
|
5160
|
+
projectId: opts.projectId,
|
|
4764
5161
|
localDebuggerUrl
|
|
4765
5162
|
});
|
|
4766
5163
|
const traceShipper = new TraceShipper2({
|
|
@@ -4772,6 +5169,7 @@ function createRaindropAISDK(opts) {
|
|
|
4772
5169
|
flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
|
|
4773
5170
|
maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
|
|
4774
5171
|
maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
|
|
5172
|
+
projectId: opts.projectId,
|
|
4775
5173
|
localDebuggerUrl,
|
|
4776
5174
|
transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
|
|
4777
5175
|
disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
|
|
@@ -4930,4 +5328,4 @@ function raindrop(options = {}) {
|
|
|
4930
5328
|
return client.createTelemetryIntegration({ context, subagentWrapping });
|
|
4931
5329
|
}
|
|
4932
5330
|
|
|
4933
|
-
export { DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent };
|
|
5331
|
+
export { DEFAULT_MAX_TEXT_FIELD_CHARS2 as DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, REDACTED_PLACEHOLDER, RaindropTelemetryIntegration, TRUNCATION_MARKER2 as TRUNCATION_MARKER, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText2 as capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent };
|