@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
package/dist/index.workers.js
CHANGED
|
@@ -4,7 +4,7 @@ var async_hooks = require('async_hooks');
|
|
|
4
4
|
|
|
5
5
|
// src/index.workers.ts
|
|
6
6
|
|
|
7
|
-
// ../core/dist/chunk-
|
|
7
|
+
// ../core/dist/chunk-SK6EJEO7.js
|
|
8
8
|
function getCrypto() {
|
|
9
9
|
const c = globalThis.crypto;
|
|
10
10
|
return c;
|
|
@@ -59,6 +59,8 @@ function base64Encode(bytes) {
|
|
|
59
59
|
}
|
|
60
60
|
return out;
|
|
61
61
|
}
|
|
62
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
63
|
+
var MAX_RETRY_DELAY_MS = 3e4;
|
|
62
64
|
function wait(ms) {
|
|
63
65
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
64
66
|
}
|
|
@@ -66,6 +68,46 @@ function formatEndpoint(endpoint) {
|
|
|
66
68
|
if (!endpoint) return void 0;
|
|
67
69
|
return endpoint.endsWith("/") ? endpoint : `${endpoint}/`;
|
|
68
70
|
}
|
|
71
|
+
function redactUrlForLog(url) {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = new URL(url);
|
|
74
|
+
parsed.username = "";
|
|
75
|
+
parsed.password = "";
|
|
76
|
+
parsed.search = "";
|
|
77
|
+
parsed.hash = "";
|
|
78
|
+
return parsed.toString();
|
|
79
|
+
} catch (e) {
|
|
80
|
+
return "<unparseable-url>";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
var RATE_LIMITED_LOG_INTERVAL_MS = 3e4;
|
|
84
|
+
var rateLimitedLogLast = /* @__PURE__ */ new Map();
|
|
85
|
+
function rateLimitedLog(key, log) {
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
const last = rateLimitedLogLast.get(key);
|
|
88
|
+
if (last !== void 0 && now - last < RATE_LIMITED_LOG_INTERVAL_MS) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
rateLimitedLogLast.set(key, now);
|
|
92
|
+
log();
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
async function raceWithTimeout(promise, timeoutMs) {
|
|
96
|
+
let timer;
|
|
97
|
+
const settledInTime = await Promise.race([
|
|
98
|
+
promise.then(
|
|
99
|
+
() => true,
|
|
100
|
+
() => true
|
|
101
|
+
),
|
|
102
|
+
new Promise((resolve) => {
|
|
103
|
+
var _a;
|
|
104
|
+
timer = setTimeout(() => resolve(false), Math.max(0, timeoutMs));
|
|
105
|
+
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
106
|
+
})
|
|
107
|
+
]);
|
|
108
|
+
if (timer) clearTimeout(timer);
|
|
109
|
+
return settledInTime;
|
|
110
|
+
}
|
|
69
111
|
function parseRetryAfter(headers) {
|
|
70
112
|
var _a;
|
|
71
113
|
const value = (_a = headers.get("Retry-After")) != null ? _a : headers.get("retry-after");
|
|
@@ -82,12 +124,12 @@ function parseRetryAfter(headers) {
|
|
|
82
124
|
function getRetryDelayMs(attemptNumber, previousError) {
|
|
83
125
|
if (previousError && typeof previousError === "object" && previousError !== null && "retryAfterMs" in previousError) {
|
|
84
126
|
const v = previousError.retryAfterMs;
|
|
85
|
-
if (typeof v === "number") return Math.max(0, v);
|
|
127
|
+
if (typeof v === "number") return Math.min(Math.max(0, v), MAX_RETRY_DELAY_MS);
|
|
86
128
|
}
|
|
87
129
|
if (attemptNumber <= 1) return 0;
|
|
88
130
|
const base = 500;
|
|
89
131
|
const factor = Math.pow(2, attemptNumber - 2);
|
|
90
|
-
return base * factor;
|
|
132
|
+
return Math.min(base * factor, MAX_RETRY_DELAY_MS);
|
|
91
133
|
}
|
|
92
134
|
async function withRetry(operation, opName2, opts) {
|
|
93
135
|
const prefix = opts.sdkName ? `[raindrop-ai/${opts.sdkName}]` : "[raindrop-ai/core]";
|
|
@@ -122,7 +164,9 @@ async function withRetry(operation, opName2, opts) {
|
|
|
122
164
|
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
123
165
|
}
|
|
124
166
|
async function postJson(url, body, headers, opts) {
|
|
125
|
-
|
|
167
|
+
var _a;
|
|
168
|
+
const opName2 = `POST ${redactUrlForLog(url)}`;
|
|
169
|
+
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
126
170
|
await withRetry(
|
|
127
171
|
async () => {
|
|
128
172
|
const resp = await fetch(url, {
|
|
@@ -131,7 +175,8 @@ async function postJson(url, body, headers, opts) {
|
|
|
131
175
|
"Content-Type": "application/json",
|
|
132
176
|
...headers
|
|
133
177
|
},
|
|
134
|
-
body: JSON.stringify(body)
|
|
178
|
+
body: JSON.stringify(body),
|
|
179
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
135
180
|
});
|
|
136
181
|
if (!resp.ok) {
|
|
137
182
|
const text = await resp.text().catch(() => "");
|
|
@@ -148,6 +193,27 @@ async function postJson(url, body, headers, opts) {
|
|
|
148
193
|
opts
|
|
149
194
|
);
|
|
150
195
|
}
|
|
196
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS = 1e6;
|
|
197
|
+
var TRUNCATION_MARKER = "...[truncated by raindrop]";
|
|
198
|
+
var currentDefaultMaxTextFieldChars = DEFAULT_MAX_TEXT_FIELD_CHARS;
|
|
199
|
+
function resolveMaxTextFieldChars(value) {
|
|
200
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
201
|
+
return Math.floor(value);
|
|
202
|
+
}
|
|
203
|
+
return currentDefaultMaxTextFieldChars;
|
|
204
|
+
}
|
|
205
|
+
function truncateToLimit(text, limit) {
|
|
206
|
+
if (limit > TRUNCATION_MARKER.length) {
|
|
207
|
+
return text.slice(0, limit - TRUNCATION_MARKER.length) + TRUNCATION_MARKER;
|
|
208
|
+
}
|
|
209
|
+
return text.slice(0, Math.max(0, limit));
|
|
210
|
+
}
|
|
211
|
+
function capText(value, limit) {
|
|
212
|
+
if (typeof value !== "string") return value;
|
|
213
|
+
const max = limit != null ? limit : currentDefaultMaxTextFieldChars;
|
|
214
|
+
if (value.length <= max) return value;
|
|
215
|
+
return truncateToLimit(value, max);
|
|
216
|
+
}
|
|
151
217
|
var SpanStatusCode = {
|
|
152
218
|
UNSET: 0,
|
|
153
219
|
ERROR: 2
|
|
@@ -335,6 +401,27 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
|
335
401
|
).catch(() => {
|
|
336
402
|
});
|
|
337
403
|
}
|
|
404
|
+
var PROJECT_ID_HEADER = "X-Raindrop-Project-Id";
|
|
405
|
+
var PROJECT_ID_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
406
|
+
function isValidProjectIdSlug(value) {
|
|
407
|
+
return PROJECT_ID_SLUG_PATTERN.test(value);
|
|
408
|
+
}
|
|
409
|
+
function normalizeProjectId(raw, opts) {
|
|
410
|
+
if (typeof raw !== "string") return void 0;
|
|
411
|
+
const trimmed = raw.trim();
|
|
412
|
+
if (!trimmed) return void 0;
|
|
413
|
+
if (!isValidProjectIdSlug(trimmed) && opts.debug) {
|
|
414
|
+
console.warn(
|
|
415
|
+
`${opts.prefix} projectId "${trimmed}" does not match slug ${PROJECT_ID_SLUG_PATTERN.source}; sending anyway \u2014 backend may reject with HTTP 400`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
return trimmed;
|
|
419
|
+
}
|
|
420
|
+
function projectIdHeaders(projectId) {
|
|
421
|
+
return projectId ? { [PROJECT_ID_HEADER]: projectId } : {};
|
|
422
|
+
}
|
|
423
|
+
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
424
|
+
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
338
425
|
function mergePatches(target, source) {
|
|
339
426
|
var _a, _b, _c, _d;
|
|
340
427
|
const out = { ...target, ...source };
|
|
@@ -352,6 +439,7 @@ var EventShipper = class {
|
|
|
352
439
|
this.sticky = /* @__PURE__ */ new Map();
|
|
353
440
|
this.timers = /* @__PURE__ */ new Map();
|
|
354
441
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
442
|
+
this.hasShutdown = false;
|
|
355
443
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
356
444
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
357
445
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -361,10 +449,15 @@ var EventShipper = class {
|
|
|
361
449
|
this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
|
|
362
450
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
363
451
|
this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
|
|
452
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
364
453
|
this.localDebuggerUrl = (_f = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _f : void 0;
|
|
365
454
|
if (this.debug && this.localDebuggerUrl) {
|
|
366
455
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
367
456
|
}
|
|
457
|
+
this.projectId = normalizeProjectId(opts.projectId, {
|
|
458
|
+
debug: this.debug,
|
|
459
|
+
prefix: this.prefix
|
|
460
|
+
});
|
|
368
461
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
369
462
|
this.context = {
|
|
370
463
|
library: {
|
|
@@ -383,10 +476,55 @@ var EventShipper = class {
|
|
|
383
476
|
authHeaders() {
|
|
384
477
|
return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
|
|
385
478
|
}
|
|
479
|
+
requestHeaders() {
|
|
480
|
+
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
484
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
485
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
486
|
+
* of issuing a request that could outlive process exit.
|
|
487
|
+
*
|
|
488
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
489
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
490
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
491
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
492
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
493
|
+
* run as a single short attempt rather than regaining the full retry
|
|
494
|
+
* schedule.
|
|
495
|
+
*/
|
|
496
|
+
requestOpts() {
|
|
497
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
498
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
499
|
+
if (remainingMs <= 0) return null;
|
|
500
|
+
return {
|
|
501
|
+
maxAttempts: 1,
|
|
502
|
+
debug: this.debug,
|
|
503
|
+
sdkName: this.sdkName,
|
|
504
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
if (this.hasShutdown) {
|
|
508
|
+
return {
|
|
509
|
+
maxAttempts: 1,
|
|
510
|
+
debug: this.debug,
|
|
511
|
+
sdkName: this.sdkName,
|
|
512
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
516
|
+
}
|
|
386
517
|
async patch(eventId, patch) {
|
|
387
518
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
388
519
|
if (!this.enabled) return;
|
|
389
520
|
if (!eventId || !eventId.trim()) return;
|
|
521
|
+
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
522
|
+
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
523
|
+
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
524
|
+
}
|
|
525
|
+
if (typeof patch.output === "string" && patch.output.length > maxChars) {
|
|
526
|
+
patch = { ...patch, output: capText(patch.output, maxChars) };
|
|
527
|
+
}
|
|
390
528
|
if (this.debug) {
|
|
391
529
|
console.log(`${this.prefix} queue patch`, {
|
|
392
530
|
eventId,
|
|
@@ -433,9 +571,16 @@ var EventShipper = class {
|
|
|
433
571
|
})));
|
|
434
572
|
}
|
|
435
573
|
async shutdown() {
|
|
436
|
-
|
|
437
|
-
this.
|
|
438
|
-
|
|
574
|
+
this.hasShutdown = true;
|
|
575
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
576
|
+
try {
|
|
577
|
+
for (const t of this.timers.values()) clearTimeout(t);
|
|
578
|
+
this.timers.clear();
|
|
579
|
+
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
580
|
+
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
581
|
+
} finally {
|
|
582
|
+
this.shutdownDeadlineAt = void 0;
|
|
583
|
+
}
|
|
439
584
|
}
|
|
440
585
|
async trackSignal(signal) {
|
|
441
586
|
var _a, _b;
|
|
@@ -457,15 +602,19 @@ var EventShipper = class {
|
|
|
457
602
|
];
|
|
458
603
|
if (!this.writeKey) return;
|
|
459
604
|
const url = `${this.baseUrl}signals/track`;
|
|
605
|
+
const opts = this.requestOpts();
|
|
606
|
+
if (!opts) {
|
|
607
|
+
this.warnShutdownDrop("signal");
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
460
610
|
try {
|
|
461
|
-
await postJson(url, body, this.
|
|
462
|
-
maxAttempts: 3,
|
|
463
|
-
debug: this.debug,
|
|
464
|
-
sdkName: this.sdkName
|
|
465
|
-
});
|
|
611
|
+
await postJson(url, body, this.requestHeaders(), opts);
|
|
466
612
|
} catch (err) {
|
|
467
613
|
const msg = err instanceof Error ? err.message : String(err);
|
|
468
|
-
|
|
614
|
+
rateLimitedLog(
|
|
615
|
+
`${this.prefix}.send_signal_failed`,
|
|
616
|
+
() => console.warn(`${this.prefix} failed to send signal (dropping): ${msg}`)
|
|
617
|
+
);
|
|
469
618
|
}
|
|
470
619
|
}
|
|
471
620
|
async identify(users) {
|
|
@@ -489,17 +638,27 @@ var EventShipper = class {
|
|
|
489
638
|
if (!this.writeKey) return;
|
|
490
639
|
if (body.length === 0) return;
|
|
491
640
|
const url = `${this.baseUrl}users/identify`;
|
|
641
|
+
const opts = this.requestOpts();
|
|
642
|
+
if (!opts) {
|
|
643
|
+
this.warnShutdownDrop("identify");
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
492
646
|
try {
|
|
493
|
-
await postJson(url, body, this.
|
|
494
|
-
maxAttempts: 3,
|
|
495
|
-
debug: this.debug,
|
|
496
|
-
sdkName: this.sdkName
|
|
497
|
-
});
|
|
647
|
+
await postJson(url, body, this.requestHeaders(), opts);
|
|
498
648
|
} catch (err) {
|
|
499
649
|
const msg = err instanceof Error ? err.message : String(err);
|
|
500
|
-
|
|
650
|
+
rateLimitedLog(
|
|
651
|
+
`${this.prefix}.send_identify_failed`,
|
|
652
|
+
() => console.warn(`${this.prefix} failed to send identify (dropping): ${msg}`)
|
|
653
|
+
);
|
|
501
654
|
}
|
|
502
655
|
}
|
|
656
|
+
warnShutdownDrop(what) {
|
|
657
|
+
rateLimitedLog(
|
|
658
|
+
`${this.prefix}.shutdown_deadline`,
|
|
659
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; dropping ${what}`)
|
|
660
|
+
);
|
|
661
|
+
}
|
|
503
662
|
async flushOne(eventId) {
|
|
504
663
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
505
664
|
if (!this.enabled) return;
|
|
@@ -575,11 +734,13 @@ var EventShipper = class {
|
|
|
575
734
|
if (!isPending) this.sticky.delete(eventId);
|
|
576
735
|
return;
|
|
577
736
|
}
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
737
|
+
const opts = this.requestOpts();
|
|
738
|
+
if (!opts) {
|
|
739
|
+
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
740
|
+
if (!isPending) this.sticky.delete(eventId);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
583
744
|
this.inFlight.add(p);
|
|
584
745
|
try {
|
|
585
746
|
try {
|
|
@@ -589,7 +750,10 @@ var EventShipper = class {
|
|
|
589
750
|
}
|
|
590
751
|
} catch (err) {
|
|
591
752
|
const msg = err instanceof Error ? err.message : String(err);
|
|
592
|
-
|
|
753
|
+
rateLimitedLog(
|
|
754
|
+
`${this.prefix}.send_track_partial_failed`,
|
|
755
|
+
() => console.warn(`${this.prefix} failed to send track_partial (dropping): ${msg}`)
|
|
756
|
+
);
|
|
593
757
|
}
|
|
594
758
|
} finally {
|
|
595
759
|
this.inFlight.delete(p);
|
|
@@ -688,10 +852,24 @@ function redactJsonAttributeValue(key, value) {
|
|
|
688
852
|
if (scrubbedJson === json) return void 0;
|
|
689
853
|
return { stringValue: scrubbedJson };
|
|
690
854
|
}
|
|
855
|
+
function applyOtelSpanAttributeLimit(limit) {
|
|
856
|
+
var _a, _b;
|
|
857
|
+
try {
|
|
858
|
+
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;
|
|
859
|
+
if (!raw) return limit;
|
|
860
|
+
const parsed = Number.parseInt(raw, 10);
|
|
861
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
862
|
+
return Math.min(limit, parsed);
|
|
863
|
+
}
|
|
864
|
+
} catch (e) {
|
|
865
|
+
}
|
|
866
|
+
return limit;
|
|
867
|
+
}
|
|
691
868
|
var TraceShipper = class {
|
|
692
869
|
constructor(opts) {
|
|
693
870
|
this.queue = [];
|
|
694
871
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
872
|
+
this.hasShutdown = false;
|
|
695
873
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
696
874
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
697
875
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -709,8 +887,45 @@ var TraceShipper = class {
|
|
|
709
887
|
if (this.debug && this.localDebuggerUrl) {
|
|
710
888
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
711
889
|
}
|
|
890
|
+
this.projectId = normalizeProjectId(opts.projectId, {
|
|
891
|
+
debug: this.debug,
|
|
892
|
+
prefix: this.prefix
|
|
893
|
+
});
|
|
712
894
|
this.transformSpanHook = opts.transformSpan;
|
|
713
895
|
this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
|
|
896
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
900
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
901
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
902
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
903
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
904
|
+
* in the surviving prefix).
|
|
905
|
+
*
|
|
906
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
907
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
908
|
+
*/
|
|
909
|
+
capSpanAttributes(span) {
|
|
910
|
+
var _a;
|
|
911
|
+
const maxChars = applyOtelSpanAttributeLimit(
|
|
912
|
+
resolveMaxTextFieldChars(this.maxTextFieldCharsOpt)
|
|
913
|
+
);
|
|
914
|
+
const attrs = span.attributes;
|
|
915
|
+
if (!attrs || attrs.length === 0) return span;
|
|
916
|
+
let nextAttrs;
|
|
917
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
918
|
+
const attr = attrs[i];
|
|
919
|
+
const value = (_a = attr.value) == null ? void 0 : _a.stringValue;
|
|
920
|
+
if (typeof value !== "string" || value.length <= maxChars) continue;
|
|
921
|
+
if (!nextAttrs) nextAttrs = attrs.slice();
|
|
922
|
+
nextAttrs[i] = {
|
|
923
|
+
key: attr.key,
|
|
924
|
+
value: { ...attr.value, stringValue: capText(value, maxChars) }
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
if (!nextAttrs) return span;
|
|
928
|
+
return { ...span, attributes: nextAttrs };
|
|
714
929
|
}
|
|
715
930
|
/**
|
|
716
931
|
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
@@ -744,7 +959,7 @@ var TraceShipper = class {
|
|
|
744
959
|
if (!this.disableDefaultRedaction) {
|
|
745
960
|
current = defaultTransformSpan(current);
|
|
746
961
|
}
|
|
747
|
-
return current;
|
|
962
|
+
return this.capSpanAttributes(current);
|
|
748
963
|
}
|
|
749
964
|
isDebugEnabled() {
|
|
750
965
|
return this.debug;
|
|
@@ -752,6 +967,9 @@ var TraceShipper = class {
|
|
|
752
967
|
authHeaders() {
|
|
753
968
|
return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
|
|
754
969
|
}
|
|
970
|
+
requestHeaders() {
|
|
971
|
+
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
972
|
+
}
|
|
755
973
|
startSpan(args) {
|
|
756
974
|
var _a, _b;
|
|
757
975
|
const ids = createSpanIds(args.parent);
|
|
@@ -865,6 +1083,16 @@ var TraceShipper = class {
|
|
|
865
1083
|
while (this.queue.length > 0) {
|
|
866
1084
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
867
1085
|
if (!this.writeKey) continue;
|
|
1086
|
+
const opts = this.requestOpts();
|
|
1087
|
+
if (!opts) {
|
|
1088
|
+
rateLimitedLog(
|
|
1089
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1090
|
+
() => console.warn(
|
|
1091
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1092
|
+
)
|
|
1093
|
+
);
|
|
1094
|
+
continue;
|
|
1095
|
+
}
|
|
868
1096
|
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
869
1097
|
const url = `${this.baseUrl}traces`;
|
|
870
1098
|
if (this.debug) {
|
|
@@ -873,11 +1101,7 @@ var TraceShipper = class {
|
|
|
873
1101
|
endpoint: url
|
|
874
1102
|
});
|
|
875
1103
|
}
|
|
876
|
-
const p = postJson(url, body, this.
|
|
877
|
-
maxAttempts: 3,
|
|
878
|
-
debug: this.debug,
|
|
879
|
-
sdkName: this.sdkName
|
|
880
|
-
});
|
|
1104
|
+
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
881
1105
|
this.inFlight.add(p);
|
|
882
1106
|
try {
|
|
883
1107
|
try {
|
|
@@ -885,21 +1109,61 @@ var TraceShipper = class {
|
|
|
885
1109
|
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
886
1110
|
} catch (err) {
|
|
887
1111
|
const msg = err instanceof Error ? err.message : String(err);
|
|
888
|
-
|
|
1112
|
+
rateLimitedLog(
|
|
1113
|
+
`${this.prefix}.send_spans_failed`,
|
|
1114
|
+
() => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
|
|
1115
|
+
);
|
|
889
1116
|
}
|
|
890
1117
|
} finally {
|
|
891
1118
|
this.inFlight.delete(p);
|
|
892
1119
|
}
|
|
893
1120
|
}
|
|
894
1121
|
}
|
|
1122
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
1123
|
+
requestOpts() {
|
|
1124
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
1125
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
1126
|
+
if (remainingMs <= 0) return null;
|
|
1127
|
+
return {
|
|
1128
|
+
maxAttempts: 1,
|
|
1129
|
+
debug: this.debug,
|
|
1130
|
+
sdkName: this.sdkName,
|
|
1131
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
if (this.hasShutdown) {
|
|
1135
|
+
return {
|
|
1136
|
+
maxAttempts: 1,
|
|
1137
|
+
debug: this.debug,
|
|
1138
|
+
sdkName: this.sdkName,
|
|
1139
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
1143
|
+
}
|
|
895
1144
|
async shutdown() {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1145
|
+
this.hasShutdown = true;
|
|
1146
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
1147
|
+
try {
|
|
1148
|
+
if (this.timer) {
|
|
1149
|
+
clearTimeout(this.timer);
|
|
1150
|
+
this.timer = void 0;
|
|
1151
|
+
}
|
|
1152
|
+
const drain = async () => {
|
|
1153
|
+
await this.flush();
|
|
1154
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1155
|
+
})));
|
|
1156
|
+
};
|
|
1157
|
+
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
1158
|
+
if (!settled) {
|
|
1159
|
+
rateLimitedLog(
|
|
1160
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1161
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
} finally {
|
|
1165
|
+
this.shutdownDeadlineAt = void 0;
|
|
899
1166
|
}
|
|
900
|
-
await this.flush();
|
|
901
|
-
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
902
|
-
})));
|
|
903
1167
|
}
|
|
904
1168
|
};
|
|
905
1169
|
var NOOP_SPAN = {
|
|
@@ -1024,7 +1288,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
|
|
|
1024
1288
|
// package.json
|
|
1025
1289
|
var package_default = {
|
|
1026
1290
|
name: "@raindrop-ai/ai-sdk",
|
|
1027
|
-
version: "0.0.
|
|
1291
|
+
version: "0.0.35"};
|
|
1028
1292
|
|
|
1029
1293
|
// src/internal/version.ts
|
|
1030
1294
|
var libraryName = package_default.name;
|
|
@@ -1043,6 +1307,133 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1043
1307
|
}
|
|
1044
1308
|
};
|
|
1045
1309
|
|
|
1310
|
+
// src/internal/truncation.ts
|
|
1311
|
+
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
1312
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
|
|
1313
|
+
var MAX_DEPTH = 12;
|
|
1314
|
+
var configuredMaxTextFieldChars;
|
|
1315
|
+
function setMaxTextFieldChars(limit) {
|
|
1316
|
+
if (limit === void 0) return;
|
|
1317
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
1318
|
+
configuredMaxTextFieldChars = Math.floor(limit);
|
|
1319
|
+
} else {
|
|
1320
|
+
console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
function otelEnvLimit() {
|
|
1324
|
+
var _a;
|
|
1325
|
+
if (typeof process === "undefined") return void 0;
|
|
1326
|
+
const raw = (_a = process.env) == null ? void 0 : _a.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
1327
|
+
if (!raw) return void 0;
|
|
1328
|
+
const parsed = Number.parseInt(raw, 10);
|
|
1329
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1330
|
+
}
|
|
1331
|
+
function effectiveMaxTextFieldChars() {
|
|
1332
|
+
const base = configuredMaxTextFieldChars != null ? configuredMaxTextFieldChars : DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
1333
|
+
const env = otelEnvLimit();
|
|
1334
|
+
return env !== void 0 && env < base ? env : base;
|
|
1335
|
+
}
|
|
1336
|
+
function truncateToLimit2(text, limit) {
|
|
1337
|
+
if (limit > TRUNCATION_MARKER2.length) {
|
|
1338
|
+
return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
|
|
1339
|
+
}
|
|
1340
|
+
return text.slice(0, limit);
|
|
1341
|
+
}
|
|
1342
|
+
function capText2(value, limit) {
|
|
1343
|
+
if (typeof value !== "string") return value;
|
|
1344
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1345
|
+
if (value.length <= max) return value;
|
|
1346
|
+
return truncateToLimit2(value, max);
|
|
1347
|
+
}
|
|
1348
|
+
function boundedClone2(value, budget, depth) {
|
|
1349
|
+
var _a, _b;
|
|
1350
|
+
if (budget.remaining <= 0) return TRUNCATION_MARKER2;
|
|
1351
|
+
if (typeof value === "string") {
|
|
1352
|
+
if (value.length > budget.remaining) {
|
|
1353
|
+
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1354
|
+
budget.remaining = 0;
|
|
1355
|
+
return taken;
|
|
1356
|
+
}
|
|
1357
|
+
budget.remaining -= Math.max(value.length, 1);
|
|
1358
|
+
return value;
|
|
1359
|
+
}
|
|
1360
|
+
if (value === null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1361
|
+
budget.remaining -= 8;
|
|
1362
|
+
return value;
|
|
1363
|
+
}
|
|
1364
|
+
if (typeof value !== "object") {
|
|
1365
|
+
budget.remaining -= 1;
|
|
1366
|
+
return value;
|
|
1367
|
+
}
|
|
1368
|
+
if (value instanceof Uint8Array) {
|
|
1369
|
+
const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
|
|
1370
|
+
if (value.byteLength > maxBytes) {
|
|
1371
|
+
const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
|
|
1372
|
+
budget.remaining = 0;
|
|
1373
|
+
return taken;
|
|
1374
|
+
}
|
|
1375
|
+
const encoded = base64Encode(value);
|
|
1376
|
+
budget.remaining -= Math.max(encoded.length, 1);
|
|
1377
|
+
return encoded;
|
|
1378
|
+
}
|
|
1379
|
+
if (depth >= MAX_DEPTH) {
|
|
1380
|
+
budget.remaining -= 16;
|
|
1381
|
+
const name = (_b = (_a = value.constructor) == null ? void 0 : _a.name) != null ? _b : "object";
|
|
1382
|
+
return `<max depth: ${name}>`;
|
|
1383
|
+
}
|
|
1384
|
+
const toJSON = value.toJSON;
|
|
1385
|
+
if (typeof toJSON === "function") {
|
|
1386
|
+
budget.remaining -= 2;
|
|
1387
|
+
return boundedClone2(toJSON.call(value), budget, depth + 1);
|
|
1388
|
+
}
|
|
1389
|
+
if (Array.isArray(value)) {
|
|
1390
|
+
budget.remaining -= 2;
|
|
1391
|
+
const out2 = [];
|
|
1392
|
+
for (const item of value) {
|
|
1393
|
+
if (budget.remaining <= 0) {
|
|
1394
|
+
out2.push(TRUNCATION_MARKER2);
|
|
1395
|
+
break;
|
|
1396
|
+
}
|
|
1397
|
+
out2.push(boundedClone2(item, budget, depth + 1));
|
|
1398
|
+
}
|
|
1399
|
+
return out2;
|
|
1400
|
+
}
|
|
1401
|
+
budget.remaining -= 2;
|
|
1402
|
+
const out = {};
|
|
1403
|
+
for (const key in value) {
|
|
1404
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
1405
|
+
if (budget.remaining <= 0) {
|
|
1406
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
1407
|
+
break;
|
|
1408
|
+
}
|
|
1409
|
+
let cappedKey = key;
|
|
1410
|
+
if (key.length > budget.remaining) {
|
|
1411
|
+
cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1412
|
+
budget.remaining = 0;
|
|
1413
|
+
out[cappedKey] = TRUNCATION_MARKER2;
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
1417
|
+
out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
|
|
1418
|
+
}
|
|
1419
|
+
return out;
|
|
1420
|
+
}
|
|
1421
|
+
function boundedStringify(value, limit) {
|
|
1422
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1423
|
+
try {
|
|
1424
|
+
if (typeof value === "string") {
|
|
1425
|
+
const text2 = JSON.stringify(capText2(value, max));
|
|
1426
|
+
return text2.length <= max ? text2 : truncateToLimit2(text2, max);
|
|
1427
|
+
}
|
|
1428
|
+
const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
1429
|
+
const text = JSON.stringify(pruned);
|
|
1430
|
+
if (text === void 0) return void 0;
|
|
1431
|
+
return text.length <= max ? text : truncateToLimit2(text, max);
|
|
1432
|
+
} catch (e) {
|
|
1433
|
+
return void 0;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1046
1437
|
// src/internal/wrap/helpers.ts
|
|
1047
1438
|
function isRecord(value) {
|
|
1048
1439
|
return typeof value === "object" && value !== null;
|
|
@@ -1067,21 +1458,10 @@ function isModuleNamespace(obj) {
|
|
|
1067
1458
|
}
|
|
1068
1459
|
}
|
|
1069
1460
|
function safeJson(value) {
|
|
1070
|
-
|
|
1071
|
-
return JSON.stringify(value);
|
|
1072
|
-
} catch (e) {
|
|
1073
|
-
return void 0;
|
|
1074
|
-
}
|
|
1461
|
+
return boundedStringify(value);
|
|
1075
1462
|
}
|
|
1076
1463
|
function safeJsonWithUint8(value) {
|
|
1077
|
-
|
|
1078
|
-
return JSON.stringify(value, (_key, v) => {
|
|
1079
|
-
if (v instanceof Uint8Array) return base64Encode(v);
|
|
1080
|
-
return v;
|
|
1081
|
-
});
|
|
1082
|
-
} catch (e) {
|
|
1083
|
-
return void 0;
|
|
1084
|
-
}
|
|
1464
|
+
return boundedStringify(value);
|
|
1085
1465
|
}
|
|
1086
1466
|
function extractModelInfo(model) {
|
|
1087
1467
|
if (typeof model === "string") {
|
|
@@ -1977,7 +2357,10 @@ var RaindropTelemetryIntegration = class {
|
|
|
1977
2357
|
inputAttrs.push(
|
|
1978
2358
|
attrStringArray(
|
|
1979
2359
|
"ai.prompt.tools",
|
|
1980
|
-
event.stepTools.map((t) =>
|
|
2360
|
+
event.stepTools.map((t) => {
|
|
2361
|
+
var _a;
|
|
2362
|
+
return (_a = safeJsonWithUint8(t)) != null ? _a : "";
|
|
2363
|
+
})
|
|
1981
2364
|
)
|
|
1982
2365
|
);
|
|
1983
2366
|
}
|
|
@@ -1985,7 +2368,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
1985
2368
|
inputAttrs.push(
|
|
1986
2369
|
attrString(
|
|
1987
2370
|
"ai.prompt.toolChoice",
|
|
1988
|
-
|
|
2371
|
+
safeJsonWithUint8(event.stepToolChoice)
|
|
1989
2372
|
)
|
|
1990
2373
|
);
|
|
1991
2374
|
}
|
|
@@ -2041,7 +2424,9 @@ var RaindropTelemetryIntegration = class {
|
|
|
2041
2424
|
if (chunk.type === "text-delta") {
|
|
2042
2425
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
2043
2426
|
if (typeof delta === "string") {
|
|
2044
|
-
state.accumulatedText
|
|
2427
|
+
if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
|
|
2428
|
+
state.accumulatedText += delta;
|
|
2429
|
+
}
|
|
2045
2430
|
this.emitLive(state, "text_delta", delta);
|
|
2046
2431
|
}
|
|
2047
2432
|
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
@@ -2060,7 +2445,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2060
2445
|
if (state.recordOutputs) {
|
|
2061
2446
|
outputAttrs.push(
|
|
2062
2447
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2063
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2448
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2064
2449
|
attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
|
|
2065
2450
|
attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
|
|
2066
2451
|
attrString(
|
|
@@ -2076,7 +2461,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2076
2461
|
outputAttrs.push(
|
|
2077
2462
|
attrString(
|
|
2078
2463
|
"ai.response.toolCalls",
|
|
2079
|
-
|
|
2464
|
+
safeJsonWithUint8(
|
|
2080
2465
|
event.toolCalls.map((tc) => ({
|
|
2081
2466
|
toolCallId: tc.toolCallId,
|
|
2082
2467
|
toolName: tc.toolName,
|
|
@@ -2089,7 +2474,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2089
2474
|
if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
|
|
2090
2475
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2091
2476
|
if (reasoningText) {
|
|
2092
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2477
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2093
2478
|
}
|
|
2094
2479
|
}
|
|
2095
2480
|
}
|
|
@@ -2511,7 +2896,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2511
2896
|
if (state.recordOutputs) {
|
|
2512
2897
|
outputAttrs.push(
|
|
2513
2898
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2514
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2899
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2515
2900
|
attrString(
|
|
2516
2901
|
"ai.response.providerMetadata",
|
|
2517
2902
|
event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
|
|
@@ -2521,7 +2906,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2521
2906
|
outputAttrs.push(
|
|
2522
2907
|
attrString(
|
|
2523
2908
|
"ai.response.toolCalls",
|
|
2524
|
-
|
|
2909
|
+
safeJsonWithUint8(
|
|
2525
2910
|
event.toolCalls.map((tc) => ({
|
|
2526
2911
|
toolCallId: tc.toolCallId,
|
|
2527
2912
|
toolName: tc.toolName,
|
|
@@ -2534,7 +2919,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2534
2919
|
if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
|
|
2535
2920
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2536
2921
|
if (reasoningText) {
|
|
2537
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2922
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2538
2923
|
}
|
|
2539
2924
|
}
|
|
2540
2925
|
}
|
|
@@ -2572,7 +2957,8 @@ var RaindropTelemetryIntegration = class {
|
|
|
2572
2957
|
const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
|
|
2573
2958
|
if (!userId) return;
|
|
2574
2959
|
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
|
|
2575
|
-
const
|
|
2960
|
+
const cappedOutput = capText2(output);
|
|
2961
|
+
const input = capText2(state.inputText);
|
|
2576
2962
|
const properties = {
|
|
2577
2963
|
...(_f = this.defaultContext) == null ? void 0 : _f.properties,
|
|
2578
2964
|
...callMeta.properties
|
|
@@ -2583,7 +2969,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2583
2969
|
userId,
|
|
2584
2970
|
convoId,
|
|
2585
2971
|
input,
|
|
2586
|
-
output,
|
|
2972
|
+
output: cappedOutput,
|
|
2587
2973
|
model,
|
|
2588
2974
|
properties: Object.keys(properties).length > 0 ? properties : void 0,
|
|
2589
2975
|
isPending: false
|
|
@@ -3056,13 +3442,14 @@ function shouldKeepEventPending(params) {
|
|
|
3056
3442
|
return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
|
|
3057
3443
|
}
|
|
3058
3444
|
function normalizePromptAttr(arg) {
|
|
3445
|
+
var _a, _b;
|
|
3059
3446
|
if (!isRecord(arg)) return arg;
|
|
3060
3447
|
const system = arg["system"];
|
|
3061
3448
|
const prompt = arg["prompt"];
|
|
3062
3449
|
const messages = arg["messages"];
|
|
3063
3450
|
if (Array.isArray(messages)) {
|
|
3064
3451
|
if (system) {
|
|
3065
|
-
const sysContent = typeof system === "string" ? system :
|
|
3452
|
+
const sysContent = typeof system === "string" ? system : (_a = safeJsonWithUint8(system)) != null ? _a : String(system);
|
|
3066
3453
|
return [{ role: "system", content: sysContent }, ...messages];
|
|
3067
3454
|
}
|
|
3068
3455
|
return messages;
|
|
@@ -3070,7 +3457,10 @@ function normalizePromptAttr(arg) {
|
|
|
3070
3457
|
if (typeof prompt === "string") {
|
|
3071
3458
|
const msgs = [];
|
|
3072
3459
|
if (system) {
|
|
3073
|
-
msgs.push({
|
|
3460
|
+
msgs.push({
|
|
3461
|
+
role: "system",
|
|
3462
|
+
content: typeof system === "string" ? system : (_b = safeJsonWithUint8(system)) != null ? _b : String(system)
|
|
3463
|
+
});
|
|
3074
3464
|
}
|
|
3075
3465
|
msgs.push({ role: "user", content: prompt });
|
|
3076
3466
|
return msgs;
|
|
@@ -3239,7 +3629,8 @@ function createFinalize(params) {
|
|
|
3239
3629
|
};
|
|
3240
3630
|
const built = await maybeBuildEvent(options.buildEvent, allMessages);
|
|
3241
3631
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3242
|
-
const output = patch.output;
|
|
3632
|
+
const output = capText2(patch.output);
|
|
3633
|
+
const input = capText2(patch.input);
|
|
3243
3634
|
const finalModel = (_c = patch.model) != null ? _c : model;
|
|
3244
3635
|
if (setup.rootSpan) {
|
|
3245
3636
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3283,7 +3674,7 @@ function createFinalize(params) {
|
|
|
3283
3674
|
eventName: patch.eventName,
|
|
3284
3675
|
userId: setup.ctx.userId,
|
|
3285
3676
|
convoId: setup.ctx.convoId,
|
|
3286
|
-
input
|
|
3677
|
+
input,
|
|
3287
3678
|
output,
|
|
3288
3679
|
model: finalModel,
|
|
3289
3680
|
properties: patch.properties,
|
|
@@ -3798,7 +4189,8 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3798
4189
|
};
|
|
3799
4190
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
3800
4191
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3801
|
-
const output = patch.output;
|
|
4192
|
+
const output = capText2(patch.output);
|
|
4193
|
+
const input = capText2(patch.input);
|
|
3802
4194
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
3803
4195
|
if (rootSpan) {
|
|
3804
4196
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3856,7 +4248,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3856
4248
|
eventName: patch.eventName,
|
|
3857
4249
|
userId: ctx.userId,
|
|
3858
4250
|
convoId: ctx.convoId,
|
|
3859
|
-
input
|
|
4251
|
+
input,
|
|
3860
4252
|
output,
|
|
3861
4253
|
model: finalModel,
|
|
3862
4254
|
properties: patch.properties,
|
|
@@ -4005,7 +4397,8 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4005
4397
|
};
|
|
4006
4398
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
4007
4399
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
4008
|
-
const output = patch.output;
|
|
4400
|
+
const output = capText2(patch.output);
|
|
4401
|
+
const input = capText2(patch.input);
|
|
4009
4402
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
4010
4403
|
if (rootSpan) {
|
|
4011
4404
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -4063,7 +4456,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4063
4456
|
eventName: patch.eventName,
|
|
4064
4457
|
userId: ctx.userId,
|
|
4065
4458
|
convoId: ctx.convoId,
|
|
4066
|
-
input
|
|
4459
|
+
input,
|
|
4067
4460
|
output,
|
|
4068
4461
|
model: finalModel,
|
|
4069
4462
|
properties: patch.properties,
|
|
@@ -4403,7 +4796,7 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4403
4796
|
attributes: [
|
|
4404
4797
|
...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
|
|
4405
4798
|
attrString("ai.response.finishReason", finishReason),
|
|
4406
|
-
attrString("ai.response.text", activeText.length ? activeText : void 0),
|
|
4799
|
+
attrString("ai.response.text", activeText.length ? capText2(activeText) : void 0),
|
|
4407
4800
|
attrString(
|
|
4408
4801
|
"ai.response.toolCalls",
|
|
4409
4802
|
safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
|
|
@@ -4456,7 +4849,9 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4456
4849
|
} else if (typeof value["textDelta"] === "string") {
|
|
4457
4850
|
textDelta = value["textDelta"];
|
|
4458
4851
|
}
|
|
4459
|
-
if (typeof textDelta === "string"
|
|
4852
|
+
if (typeof textDelta === "string" && activeText.length <= effectiveMaxTextFieldChars()) {
|
|
4853
|
+
activeText += textDelta;
|
|
4854
|
+
}
|
|
4460
4855
|
}
|
|
4461
4856
|
if (type === "finish") finishReason = extractFinishReason(value);
|
|
4462
4857
|
if (type === "tool-call") toolCallsLocal.push(value);
|
|
@@ -4729,8 +5124,8 @@ function eventMetadataFromChatRequest(options) {
|
|
|
4729
5124
|
});
|
|
4730
5125
|
}
|
|
4731
5126
|
function stringify(v) {
|
|
4732
|
-
if (typeof v === "string") return v;
|
|
4733
|
-
return
|
|
5127
|
+
if (typeof v === "string") return capText2(v);
|
|
5128
|
+
return boundedStringify(v);
|
|
4734
5129
|
}
|
|
4735
5130
|
function userAttrsToOtlp(attrs) {
|
|
4736
5131
|
if (!attrs) return [];
|
|
@@ -4748,6 +5143,7 @@ function createRaindropAISDK(opts) {
|
|
|
4748
5143
|
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
4749
5144
|
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
4750
5145
|
const envDebug = envDebugEnabled();
|
|
5146
|
+
setMaxTextFieldChars(opts.maxTextFieldChars);
|
|
4751
5147
|
const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
|
|
4752
5148
|
const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
|
|
4753
5149
|
const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
|
|
@@ -4765,6 +5161,7 @@ function createRaindropAISDK(opts) {
|
|
|
4765
5161
|
enabled: eventsEnabled,
|
|
4766
5162
|
debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
|
|
4767
5163
|
partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
|
|
5164
|
+
projectId: opts.projectId,
|
|
4768
5165
|
localDebuggerUrl
|
|
4769
5166
|
});
|
|
4770
5167
|
const traceShipper = new TraceShipper2({
|
|
@@ -4776,6 +5173,7 @@ function createRaindropAISDK(opts) {
|
|
|
4776
5173
|
flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
|
|
4777
5174
|
maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
|
|
4778
5175
|
maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
|
|
5176
|
+
projectId: opts.projectId,
|
|
4779
5177
|
localDebuggerUrl,
|
|
4780
5178
|
transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
|
|
4781
5179
|
disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
|
|
@@ -4939,13 +5337,17 @@ if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
|
4939
5337
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
|
|
4940
5338
|
}
|
|
4941
5339
|
|
|
5340
|
+
exports.DEFAULT_MAX_TEXT_FIELD_CHARS = DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
4942
5341
|
exports.DEFAULT_REDACT_ATTRIBUTE_KEYS = DEFAULT_REDACT_ATTRIBUTE_KEYS;
|
|
4943
5342
|
exports.DEFAULT_SECRET_KEY_NAMES = DEFAULT_SECRET_KEY_NAMES;
|
|
4944
5343
|
exports.REDACTED_PLACEHOLDER = REDACTED_PLACEHOLDER;
|
|
4945
5344
|
exports.RaindropTelemetryIntegration = RaindropTelemetryIntegration;
|
|
5345
|
+
exports.TRUNCATION_MARKER = TRUNCATION_MARKER2;
|
|
4946
5346
|
exports._resetParentToolContextStorage = _resetParentToolContextStorage;
|
|
4947
5347
|
exports._resetRaindropCallMetadataStorage = _resetRaindropCallMetadataStorage;
|
|
4948
5348
|
exports._resetWarnedMissingUserId = _resetWarnedMissingUserId;
|
|
5349
|
+
exports.boundedStringify = boundedStringify;
|
|
5350
|
+
exports.capText = capText2;
|
|
4949
5351
|
exports.clearParentToolContext = clearParentToolContext;
|
|
4950
5352
|
exports.createRaindropAISDK = createRaindropAISDK;
|
|
4951
5353
|
exports.currentSpan = currentSpan;
|