@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.browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
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 = {
|
|
@@ -1019,7 +1283,7 @@ async function* asyncGeneratorWithCurrent(span, gen) {
|
|
|
1019
1283
|
// package.json
|
|
1020
1284
|
var package_default = {
|
|
1021
1285
|
name: "@raindrop-ai/ai-sdk",
|
|
1022
|
-
version: "0.0.
|
|
1286
|
+
version: "0.0.35"};
|
|
1023
1287
|
|
|
1024
1288
|
// src/internal/version.ts
|
|
1025
1289
|
var libraryName = package_default.name;
|
|
@@ -1038,6 +1302,133 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1038
1302
|
}
|
|
1039
1303
|
};
|
|
1040
1304
|
|
|
1305
|
+
// src/internal/truncation.ts
|
|
1306
|
+
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
1307
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
|
|
1308
|
+
var MAX_DEPTH = 12;
|
|
1309
|
+
var configuredMaxTextFieldChars;
|
|
1310
|
+
function setMaxTextFieldChars(limit) {
|
|
1311
|
+
if (limit === void 0) return;
|
|
1312
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
1313
|
+
configuredMaxTextFieldChars = Math.floor(limit);
|
|
1314
|
+
} else {
|
|
1315
|
+
console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
function otelEnvLimit() {
|
|
1319
|
+
var _a;
|
|
1320
|
+
if (typeof process === "undefined") return void 0;
|
|
1321
|
+
const raw = (_a = process.env) == null ? void 0 : _a.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
1322
|
+
if (!raw) return void 0;
|
|
1323
|
+
const parsed = Number.parseInt(raw, 10);
|
|
1324
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1325
|
+
}
|
|
1326
|
+
function effectiveMaxTextFieldChars() {
|
|
1327
|
+
const base = configuredMaxTextFieldChars != null ? configuredMaxTextFieldChars : DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
1328
|
+
const env = otelEnvLimit();
|
|
1329
|
+
return env !== void 0 && env < base ? env : base;
|
|
1330
|
+
}
|
|
1331
|
+
function truncateToLimit2(text, limit) {
|
|
1332
|
+
if (limit > TRUNCATION_MARKER2.length) {
|
|
1333
|
+
return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
|
|
1334
|
+
}
|
|
1335
|
+
return text.slice(0, limit);
|
|
1336
|
+
}
|
|
1337
|
+
function capText2(value, limit) {
|
|
1338
|
+
if (typeof value !== "string") return value;
|
|
1339
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1340
|
+
if (value.length <= max) return value;
|
|
1341
|
+
return truncateToLimit2(value, max);
|
|
1342
|
+
}
|
|
1343
|
+
function boundedClone2(value, budget, depth) {
|
|
1344
|
+
var _a, _b;
|
|
1345
|
+
if (budget.remaining <= 0) return TRUNCATION_MARKER2;
|
|
1346
|
+
if (typeof value === "string") {
|
|
1347
|
+
if (value.length > budget.remaining) {
|
|
1348
|
+
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1349
|
+
budget.remaining = 0;
|
|
1350
|
+
return taken;
|
|
1351
|
+
}
|
|
1352
|
+
budget.remaining -= Math.max(value.length, 1);
|
|
1353
|
+
return value;
|
|
1354
|
+
}
|
|
1355
|
+
if (value === null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1356
|
+
budget.remaining -= 8;
|
|
1357
|
+
return value;
|
|
1358
|
+
}
|
|
1359
|
+
if (typeof value !== "object") {
|
|
1360
|
+
budget.remaining -= 1;
|
|
1361
|
+
return value;
|
|
1362
|
+
}
|
|
1363
|
+
if (value instanceof Uint8Array) {
|
|
1364
|
+
const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
|
|
1365
|
+
if (value.byteLength > maxBytes) {
|
|
1366
|
+
const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
|
|
1367
|
+
budget.remaining = 0;
|
|
1368
|
+
return taken;
|
|
1369
|
+
}
|
|
1370
|
+
const encoded = base64Encode(value);
|
|
1371
|
+
budget.remaining -= Math.max(encoded.length, 1);
|
|
1372
|
+
return encoded;
|
|
1373
|
+
}
|
|
1374
|
+
if (depth >= MAX_DEPTH) {
|
|
1375
|
+
budget.remaining -= 16;
|
|
1376
|
+
const name = (_b = (_a = value.constructor) == null ? void 0 : _a.name) != null ? _b : "object";
|
|
1377
|
+
return `<max depth: ${name}>`;
|
|
1378
|
+
}
|
|
1379
|
+
const toJSON = value.toJSON;
|
|
1380
|
+
if (typeof toJSON === "function") {
|
|
1381
|
+
budget.remaining -= 2;
|
|
1382
|
+
return boundedClone2(toJSON.call(value), budget, depth + 1);
|
|
1383
|
+
}
|
|
1384
|
+
if (Array.isArray(value)) {
|
|
1385
|
+
budget.remaining -= 2;
|
|
1386
|
+
const out2 = [];
|
|
1387
|
+
for (const item of value) {
|
|
1388
|
+
if (budget.remaining <= 0) {
|
|
1389
|
+
out2.push(TRUNCATION_MARKER2);
|
|
1390
|
+
break;
|
|
1391
|
+
}
|
|
1392
|
+
out2.push(boundedClone2(item, budget, depth + 1));
|
|
1393
|
+
}
|
|
1394
|
+
return out2;
|
|
1395
|
+
}
|
|
1396
|
+
budget.remaining -= 2;
|
|
1397
|
+
const out = {};
|
|
1398
|
+
for (const key in value) {
|
|
1399
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
1400
|
+
if (budget.remaining <= 0) {
|
|
1401
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
1402
|
+
break;
|
|
1403
|
+
}
|
|
1404
|
+
let cappedKey = key;
|
|
1405
|
+
if (key.length > budget.remaining) {
|
|
1406
|
+
cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1407
|
+
budget.remaining = 0;
|
|
1408
|
+
out[cappedKey] = TRUNCATION_MARKER2;
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
1412
|
+
out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
|
|
1413
|
+
}
|
|
1414
|
+
return out;
|
|
1415
|
+
}
|
|
1416
|
+
function boundedStringify(value, limit) {
|
|
1417
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1418
|
+
try {
|
|
1419
|
+
if (typeof value === "string") {
|
|
1420
|
+
const text2 = JSON.stringify(capText2(value, max));
|
|
1421
|
+
return text2.length <= max ? text2 : truncateToLimit2(text2, max);
|
|
1422
|
+
}
|
|
1423
|
+
const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
1424
|
+
const text = JSON.stringify(pruned);
|
|
1425
|
+
if (text === void 0) return void 0;
|
|
1426
|
+
return text.length <= max ? text : truncateToLimit2(text, max);
|
|
1427
|
+
} catch (e) {
|
|
1428
|
+
return void 0;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1041
1432
|
// src/internal/wrap/helpers.ts
|
|
1042
1433
|
function isRecord(value) {
|
|
1043
1434
|
return typeof value === "object" && value !== null;
|
|
@@ -1062,21 +1453,10 @@ function isModuleNamespace(obj) {
|
|
|
1062
1453
|
}
|
|
1063
1454
|
}
|
|
1064
1455
|
function safeJson(value) {
|
|
1065
|
-
|
|
1066
|
-
return JSON.stringify(value);
|
|
1067
|
-
} catch (e) {
|
|
1068
|
-
return void 0;
|
|
1069
|
-
}
|
|
1456
|
+
return boundedStringify(value);
|
|
1070
1457
|
}
|
|
1071
1458
|
function safeJsonWithUint8(value) {
|
|
1072
|
-
|
|
1073
|
-
return JSON.stringify(value, (_key, v) => {
|
|
1074
|
-
if (v instanceof Uint8Array) return base64Encode(v);
|
|
1075
|
-
return v;
|
|
1076
|
-
});
|
|
1077
|
-
} catch (e) {
|
|
1078
|
-
return void 0;
|
|
1079
|
-
}
|
|
1459
|
+
return boundedStringify(value);
|
|
1080
1460
|
}
|
|
1081
1461
|
function extractModelInfo(model) {
|
|
1082
1462
|
if (typeof model === "string") {
|
|
@@ -1972,7 +2352,10 @@ var RaindropTelemetryIntegration = class {
|
|
|
1972
2352
|
inputAttrs.push(
|
|
1973
2353
|
attrStringArray(
|
|
1974
2354
|
"ai.prompt.tools",
|
|
1975
|
-
event.stepTools.map((t) =>
|
|
2355
|
+
event.stepTools.map((t) => {
|
|
2356
|
+
var _a;
|
|
2357
|
+
return (_a = safeJsonWithUint8(t)) != null ? _a : "";
|
|
2358
|
+
})
|
|
1976
2359
|
)
|
|
1977
2360
|
);
|
|
1978
2361
|
}
|
|
@@ -1980,7 +2363,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
1980
2363
|
inputAttrs.push(
|
|
1981
2364
|
attrString(
|
|
1982
2365
|
"ai.prompt.toolChoice",
|
|
1983
|
-
|
|
2366
|
+
safeJsonWithUint8(event.stepToolChoice)
|
|
1984
2367
|
)
|
|
1985
2368
|
);
|
|
1986
2369
|
}
|
|
@@ -2036,7 +2419,9 @@ var RaindropTelemetryIntegration = class {
|
|
|
2036
2419
|
if (chunk.type === "text-delta") {
|
|
2037
2420
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
2038
2421
|
if (typeof delta === "string") {
|
|
2039
|
-
state.accumulatedText
|
|
2422
|
+
if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
|
|
2423
|
+
state.accumulatedText += delta;
|
|
2424
|
+
}
|
|
2040
2425
|
this.emitLive(state, "text_delta", delta);
|
|
2041
2426
|
}
|
|
2042
2427
|
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
@@ -2055,7 +2440,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2055
2440
|
if (state.recordOutputs) {
|
|
2056
2441
|
outputAttrs.push(
|
|
2057
2442
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2058
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2443
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2059
2444
|
attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
|
|
2060
2445
|
attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
|
|
2061
2446
|
attrString(
|
|
@@ -2071,7 +2456,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2071
2456
|
outputAttrs.push(
|
|
2072
2457
|
attrString(
|
|
2073
2458
|
"ai.response.toolCalls",
|
|
2074
|
-
|
|
2459
|
+
safeJsonWithUint8(
|
|
2075
2460
|
event.toolCalls.map((tc) => ({
|
|
2076
2461
|
toolCallId: tc.toolCallId,
|
|
2077
2462
|
toolName: tc.toolName,
|
|
@@ -2084,7 +2469,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2084
2469
|
if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
|
|
2085
2470
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2086
2471
|
if (reasoningText) {
|
|
2087
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2472
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2088
2473
|
}
|
|
2089
2474
|
}
|
|
2090
2475
|
}
|
|
@@ -2506,7 +2891,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2506
2891
|
if (state.recordOutputs) {
|
|
2507
2892
|
outputAttrs.push(
|
|
2508
2893
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2509
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2894
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2510
2895
|
attrString(
|
|
2511
2896
|
"ai.response.providerMetadata",
|
|
2512
2897
|
event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
|
|
@@ -2516,7 +2901,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2516
2901
|
outputAttrs.push(
|
|
2517
2902
|
attrString(
|
|
2518
2903
|
"ai.response.toolCalls",
|
|
2519
|
-
|
|
2904
|
+
safeJsonWithUint8(
|
|
2520
2905
|
event.toolCalls.map((tc) => ({
|
|
2521
2906
|
toolCallId: tc.toolCallId,
|
|
2522
2907
|
toolName: tc.toolName,
|
|
@@ -2529,7 +2914,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2529
2914
|
if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
|
|
2530
2915
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2531
2916
|
if (reasoningText) {
|
|
2532
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2917
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2533
2918
|
}
|
|
2534
2919
|
}
|
|
2535
2920
|
}
|
|
@@ -2567,7 +2952,8 @@ var RaindropTelemetryIntegration = class {
|
|
|
2567
2952
|
const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
|
|
2568
2953
|
if (!userId) return;
|
|
2569
2954
|
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
|
|
2570
|
-
const
|
|
2955
|
+
const cappedOutput = capText2(output);
|
|
2956
|
+
const input = capText2(state.inputText);
|
|
2571
2957
|
const properties = {
|
|
2572
2958
|
...(_f = this.defaultContext) == null ? void 0 : _f.properties,
|
|
2573
2959
|
...callMeta.properties
|
|
@@ -2578,7 +2964,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2578
2964
|
userId,
|
|
2579
2965
|
convoId,
|
|
2580
2966
|
input,
|
|
2581
|
-
output,
|
|
2967
|
+
output: cappedOutput,
|
|
2582
2968
|
model,
|
|
2583
2969
|
properties: Object.keys(properties).length > 0 ? properties : void 0,
|
|
2584
2970
|
isPending: false
|
|
@@ -3051,13 +3437,14 @@ function shouldKeepEventPending(params) {
|
|
|
3051
3437
|
return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
|
|
3052
3438
|
}
|
|
3053
3439
|
function normalizePromptAttr(arg) {
|
|
3440
|
+
var _a, _b;
|
|
3054
3441
|
if (!isRecord(arg)) return arg;
|
|
3055
3442
|
const system = arg["system"];
|
|
3056
3443
|
const prompt = arg["prompt"];
|
|
3057
3444
|
const messages = arg["messages"];
|
|
3058
3445
|
if (Array.isArray(messages)) {
|
|
3059
3446
|
if (system) {
|
|
3060
|
-
const sysContent = typeof system === "string" ? system :
|
|
3447
|
+
const sysContent = typeof system === "string" ? system : (_a = safeJsonWithUint8(system)) != null ? _a : String(system);
|
|
3061
3448
|
return [{ role: "system", content: sysContent }, ...messages];
|
|
3062
3449
|
}
|
|
3063
3450
|
return messages;
|
|
@@ -3065,7 +3452,10 @@ function normalizePromptAttr(arg) {
|
|
|
3065
3452
|
if (typeof prompt === "string") {
|
|
3066
3453
|
const msgs = [];
|
|
3067
3454
|
if (system) {
|
|
3068
|
-
msgs.push({
|
|
3455
|
+
msgs.push({
|
|
3456
|
+
role: "system",
|
|
3457
|
+
content: typeof system === "string" ? system : (_b = safeJsonWithUint8(system)) != null ? _b : String(system)
|
|
3458
|
+
});
|
|
3069
3459
|
}
|
|
3070
3460
|
msgs.push({ role: "user", content: prompt });
|
|
3071
3461
|
return msgs;
|
|
@@ -3234,7 +3624,8 @@ function createFinalize(params) {
|
|
|
3234
3624
|
};
|
|
3235
3625
|
const built = await maybeBuildEvent(options.buildEvent, allMessages);
|
|
3236
3626
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3237
|
-
const output = patch.output;
|
|
3627
|
+
const output = capText2(patch.output);
|
|
3628
|
+
const input = capText2(patch.input);
|
|
3238
3629
|
const finalModel = (_c = patch.model) != null ? _c : model;
|
|
3239
3630
|
if (setup.rootSpan) {
|
|
3240
3631
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3278,7 +3669,7 @@ function createFinalize(params) {
|
|
|
3278
3669
|
eventName: patch.eventName,
|
|
3279
3670
|
userId: setup.ctx.userId,
|
|
3280
3671
|
convoId: setup.ctx.convoId,
|
|
3281
|
-
input
|
|
3672
|
+
input,
|
|
3282
3673
|
output,
|
|
3283
3674
|
model: finalModel,
|
|
3284
3675
|
properties: patch.properties,
|
|
@@ -3793,7 +4184,8 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3793
4184
|
};
|
|
3794
4185
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
3795
4186
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3796
|
-
const output = patch.output;
|
|
4187
|
+
const output = capText2(patch.output);
|
|
4188
|
+
const input = capText2(patch.input);
|
|
3797
4189
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
3798
4190
|
if (rootSpan) {
|
|
3799
4191
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3851,7 +4243,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3851
4243
|
eventName: patch.eventName,
|
|
3852
4244
|
userId: ctx.userId,
|
|
3853
4245
|
convoId: ctx.convoId,
|
|
3854
|
-
input
|
|
4246
|
+
input,
|
|
3855
4247
|
output,
|
|
3856
4248
|
model: finalModel,
|
|
3857
4249
|
properties: patch.properties,
|
|
@@ -4000,7 +4392,8 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4000
4392
|
};
|
|
4001
4393
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
4002
4394
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
4003
|
-
const output = patch.output;
|
|
4395
|
+
const output = capText2(patch.output);
|
|
4396
|
+
const input = capText2(patch.input);
|
|
4004
4397
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
4005
4398
|
if (rootSpan) {
|
|
4006
4399
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -4058,7 +4451,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4058
4451
|
eventName: patch.eventName,
|
|
4059
4452
|
userId: ctx.userId,
|
|
4060
4453
|
convoId: ctx.convoId,
|
|
4061
|
-
input
|
|
4454
|
+
input,
|
|
4062
4455
|
output,
|
|
4063
4456
|
model: finalModel,
|
|
4064
4457
|
properties: patch.properties,
|
|
@@ -4398,7 +4791,7 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4398
4791
|
attributes: [
|
|
4399
4792
|
...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
|
|
4400
4793
|
attrString("ai.response.finishReason", finishReason),
|
|
4401
|
-
attrString("ai.response.text", activeText.length ? activeText : void 0),
|
|
4794
|
+
attrString("ai.response.text", activeText.length ? capText2(activeText) : void 0),
|
|
4402
4795
|
attrString(
|
|
4403
4796
|
"ai.response.toolCalls",
|
|
4404
4797
|
safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
|
|
@@ -4451,7 +4844,9 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4451
4844
|
} else if (typeof value["textDelta"] === "string") {
|
|
4452
4845
|
textDelta = value["textDelta"];
|
|
4453
4846
|
}
|
|
4454
|
-
if (typeof textDelta === "string"
|
|
4847
|
+
if (typeof textDelta === "string" && activeText.length <= effectiveMaxTextFieldChars()) {
|
|
4848
|
+
activeText += textDelta;
|
|
4849
|
+
}
|
|
4455
4850
|
}
|
|
4456
4851
|
if (type === "finish") finishReason = extractFinishReason(value);
|
|
4457
4852
|
if (type === "tool-call") toolCallsLocal.push(value);
|
|
@@ -4724,8 +5119,8 @@ function eventMetadataFromChatRequest(options) {
|
|
|
4724
5119
|
});
|
|
4725
5120
|
}
|
|
4726
5121
|
function stringify(v) {
|
|
4727
|
-
if (typeof v === "string") return v;
|
|
4728
|
-
return
|
|
5122
|
+
if (typeof v === "string") return capText2(v);
|
|
5123
|
+
return boundedStringify(v);
|
|
4729
5124
|
}
|
|
4730
5125
|
function userAttrsToOtlp(attrs) {
|
|
4731
5126
|
if (!attrs) return [];
|
|
@@ -4743,6 +5138,7 @@ function createRaindropAISDK(opts) {
|
|
|
4743
5138
|
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
4744
5139
|
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
4745
5140
|
const envDebug = envDebugEnabled();
|
|
5141
|
+
setMaxTextFieldChars(opts.maxTextFieldChars);
|
|
4746
5142
|
const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
|
|
4747
5143
|
const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
|
|
4748
5144
|
const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
|
|
@@ -4760,6 +5156,7 @@ function createRaindropAISDK(opts) {
|
|
|
4760
5156
|
enabled: eventsEnabled,
|
|
4761
5157
|
debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
|
|
4762
5158
|
partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
|
|
5159
|
+
projectId: opts.projectId,
|
|
4763
5160
|
localDebuggerUrl
|
|
4764
5161
|
});
|
|
4765
5162
|
const traceShipper = new TraceShipper2({
|
|
@@ -4771,6 +5168,7 @@ function createRaindropAISDK(opts) {
|
|
|
4771
5168
|
flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
|
|
4772
5169
|
maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
|
|
4773
5170
|
maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
|
|
5171
|
+
projectId: opts.projectId,
|
|
4774
5172
|
localDebuggerUrl,
|
|
4775
5173
|
transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
|
|
4776
5174
|
disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
|
|
@@ -4929,13 +5327,17 @@ function raindrop(options = {}) {
|
|
|
4929
5327
|
return client.createTelemetryIntegration({ context, subagentWrapping });
|
|
4930
5328
|
}
|
|
4931
5329
|
|
|
5330
|
+
exports.DEFAULT_MAX_TEXT_FIELD_CHARS = DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
4932
5331
|
exports.DEFAULT_REDACT_ATTRIBUTE_KEYS = DEFAULT_REDACT_ATTRIBUTE_KEYS;
|
|
4933
5332
|
exports.DEFAULT_SECRET_KEY_NAMES = DEFAULT_SECRET_KEY_NAMES;
|
|
4934
5333
|
exports.REDACTED_PLACEHOLDER = REDACTED_PLACEHOLDER;
|
|
4935
5334
|
exports.RaindropTelemetryIntegration = RaindropTelemetryIntegration;
|
|
5335
|
+
exports.TRUNCATION_MARKER = TRUNCATION_MARKER2;
|
|
4936
5336
|
exports._resetParentToolContextStorage = _resetParentToolContextStorage;
|
|
4937
5337
|
exports._resetRaindropCallMetadataStorage = _resetRaindropCallMetadataStorage;
|
|
4938
5338
|
exports._resetWarnedMissingUserId = _resetWarnedMissingUserId;
|
|
5339
|
+
exports.boundedStringify = boundedStringify;
|
|
5340
|
+
exports.capText = capText2;
|
|
4939
5341
|
exports.clearParentToolContext = clearParentToolContext;
|
|
4940
5342
|
exports.createRaindropAISDK = createRaindropAISDK;
|
|
4941
5343
|
exports.currentSpan = currentSpan;
|