@raindrop-ai/ai-sdk 0.0.33 → 0.0.34
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-OLOFN54C.mjs} +440 -77
- package/dist/{index-Dcf4FPZL.d.mts → index-HYjRP6nV.d.mts} +112 -2
- package/dist/{index-Dcf4FPZL.d.ts → index-HYjRP6nV.d.ts} +112 -2
- package/dist/index.browser.d.mts +112 -2
- package/dist/index.browser.d.ts +112 -2
- package/dist/index.browser.js +443 -76
- package/dist/index.browser.mjs +440 -77
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.js +443 -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 +443 -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-U5HUTMR5.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,8 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
|
335
401
|
).catch(() => {
|
|
336
402
|
});
|
|
337
403
|
}
|
|
404
|
+
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
405
|
+
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
338
406
|
function mergePatches(target, source) {
|
|
339
407
|
var _a, _b, _c, _d;
|
|
340
408
|
const out = { ...target, ...source };
|
|
@@ -352,6 +420,7 @@ var EventShipper = class {
|
|
|
352
420
|
this.sticky = /* @__PURE__ */ new Map();
|
|
353
421
|
this.timers = /* @__PURE__ */ new Map();
|
|
354
422
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
423
|
+
this.hasShutdown = false;
|
|
355
424
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
356
425
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
357
426
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -361,6 +430,7 @@ var EventShipper = class {
|
|
|
361
430
|
this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
|
|
362
431
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
363
432
|
this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
|
|
433
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
364
434
|
this.localDebuggerUrl = (_f = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _f : void 0;
|
|
365
435
|
if (this.debug && this.localDebuggerUrl) {
|
|
366
436
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
@@ -383,10 +453,52 @@ var EventShipper = class {
|
|
|
383
453
|
authHeaders() {
|
|
384
454
|
return this.writeKey ? { Authorization: `Bearer ${this.writeKey}` } : {};
|
|
385
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
458
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
459
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
460
|
+
* of issuing a request that could outlive process exit.
|
|
461
|
+
*
|
|
462
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
463
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
464
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
465
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
466
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
467
|
+
* run as a single short attempt rather than regaining the full retry
|
|
468
|
+
* schedule.
|
|
469
|
+
*/
|
|
470
|
+
requestOpts() {
|
|
471
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
472
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
473
|
+
if (remainingMs <= 0) return null;
|
|
474
|
+
return {
|
|
475
|
+
maxAttempts: 1,
|
|
476
|
+
debug: this.debug,
|
|
477
|
+
sdkName: this.sdkName,
|
|
478
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
if (this.hasShutdown) {
|
|
482
|
+
return {
|
|
483
|
+
maxAttempts: 1,
|
|
484
|
+
debug: this.debug,
|
|
485
|
+
sdkName: this.sdkName,
|
|
486
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
490
|
+
}
|
|
386
491
|
async patch(eventId, patch) {
|
|
387
492
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
388
493
|
if (!this.enabled) return;
|
|
389
494
|
if (!eventId || !eventId.trim()) return;
|
|
495
|
+
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
496
|
+
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
497
|
+
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
498
|
+
}
|
|
499
|
+
if (typeof patch.output === "string" && patch.output.length > maxChars) {
|
|
500
|
+
patch = { ...patch, output: capText(patch.output, maxChars) };
|
|
501
|
+
}
|
|
390
502
|
if (this.debug) {
|
|
391
503
|
console.log(`${this.prefix} queue patch`, {
|
|
392
504
|
eventId,
|
|
@@ -433,9 +545,16 @@ var EventShipper = class {
|
|
|
433
545
|
})));
|
|
434
546
|
}
|
|
435
547
|
async shutdown() {
|
|
436
|
-
|
|
437
|
-
this.
|
|
438
|
-
|
|
548
|
+
this.hasShutdown = true;
|
|
549
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
550
|
+
try {
|
|
551
|
+
for (const t of this.timers.values()) clearTimeout(t);
|
|
552
|
+
this.timers.clear();
|
|
553
|
+
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
554
|
+
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
555
|
+
} finally {
|
|
556
|
+
this.shutdownDeadlineAt = void 0;
|
|
557
|
+
}
|
|
439
558
|
}
|
|
440
559
|
async trackSignal(signal) {
|
|
441
560
|
var _a, _b;
|
|
@@ -457,15 +576,19 @@ var EventShipper = class {
|
|
|
457
576
|
];
|
|
458
577
|
if (!this.writeKey) return;
|
|
459
578
|
const url = `${this.baseUrl}signals/track`;
|
|
579
|
+
const opts = this.requestOpts();
|
|
580
|
+
if (!opts) {
|
|
581
|
+
this.warnShutdownDrop("signal");
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
460
584
|
try {
|
|
461
|
-
await postJson(url, body, this.authHeaders(),
|
|
462
|
-
maxAttempts: 3,
|
|
463
|
-
debug: this.debug,
|
|
464
|
-
sdkName: this.sdkName
|
|
465
|
-
});
|
|
585
|
+
await postJson(url, body, this.authHeaders(), opts);
|
|
466
586
|
} catch (err) {
|
|
467
587
|
const msg = err instanceof Error ? err.message : String(err);
|
|
468
|
-
|
|
588
|
+
rateLimitedLog(
|
|
589
|
+
`${this.prefix}.send_signal_failed`,
|
|
590
|
+
() => console.warn(`${this.prefix} failed to send signal (dropping): ${msg}`)
|
|
591
|
+
);
|
|
469
592
|
}
|
|
470
593
|
}
|
|
471
594
|
async identify(users) {
|
|
@@ -489,17 +612,27 @@ var EventShipper = class {
|
|
|
489
612
|
if (!this.writeKey) return;
|
|
490
613
|
if (body.length === 0) return;
|
|
491
614
|
const url = `${this.baseUrl}users/identify`;
|
|
615
|
+
const opts = this.requestOpts();
|
|
616
|
+
if (!opts) {
|
|
617
|
+
this.warnShutdownDrop("identify");
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
492
620
|
try {
|
|
493
|
-
await postJson(url, body, this.authHeaders(),
|
|
494
|
-
maxAttempts: 3,
|
|
495
|
-
debug: this.debug,
|
|
496
|
-
sdkName: this.sdkName
|
|
497
|
-
});
|
|
621
|
+
await postJson(url, body, this.authHeaders(), opts);
|
|
498
622
|
} catch (err) {
|
|
499
623
|
const msg = err instanceof Error ? err.message : String(err);
|
|
500
|
-
|
|
624
|
+
rateLimitedLog(
|
|
625
|
+
`${this.prefix}.send_identify_failed`,
|
|
626
|
+
() => console.warn(`${this.prefix} failed to send identify (dropping): ${msg}`)
|
|
627
|
+
);
|
|
501
628
|
}
|
|
502
629
|
}
|
|
630
|
+
warnShutdownDrop(what) {
|
|
631
|
+
rateLimitedLog(
|
|
632
|
+
`${this.prefix}.shutdown_deadline`,
|
|
633
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; dropping ${what}`)
|
|
634
|
+
);
|
|
635
|
+
}
|
|
503
636
|
async flushOne(eventId) {
|
|
504
637
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
505
638
|
if (!this.enabled) return;
|
|
@@ -575,11 +708,13 @@ var EventShipper = class {
|
|
|
575
708
|
if (!isPending) this.sticky.delete(eventId);
|
|
576
709
|
return;
|
|
577
710
|
}
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
711
|
+
const opts = this.requestOpts();
|
|
712
|
+
if (!opts) {
|
|
713
|
+
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
714
|
+
if (!isPending) this.sticky.delete(eventId);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
const p = postJson(url, payload, this.authHeaders(), opts);
|
|
583
718
|
this.inFlight.add(p);
|
|
584
719
|
try {
|
|
585
720
|
try {
|
|
@@ -589,7 +724,10 @@ var EventShipper = class {
|
|
|
589
724
|
}
|
|
590
725
|
} catch (err) {
|
|
591
726
|
const msg = err instanceof Error ? err.message : String(err);
|
|
592
|
-
|
|
727
|
+
rateLimitedLog(
|
|
728
|
+
`${this.prefix}.send_track_partial_failed`,
|
|
729
|
+
() => console.warn(`${this.prefix} failed to send track_partial (dropping): ${msg}`)
|
|
730
|
+
);
|
|
593
731
|
}
|
|
594
732
|
} finally {
|
|
595
733
|
this.inFlight.delete(p);
|
|
@@ -688,10 +826,24 @@ function redactJsonAttributeValue(key, value) {
|
|
|
688
826
|
if (scrubbedJson === json) return void 0;
|
|
689
827
|
return { stringValue: scrubbedJson };
|
|
690
828
|
}
|
|
829
|
+
function applyOtelSpanAttributeLimit(limit) {
|
|
830
|
+
var _a, _b;
|
|
831
|
+
try {
|
|
832
|
+
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;
|
|
833
|
+
if (!raw) return limit;
|
|
834
|
+
const parsed = Number.parseInt(raw, 10);
|
|
835
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
836
|
+
return Math.min(limit, parsed);
|
|
837
|
+
}
|
|
838
|
+
} catch (e) {
|
|
839
|
+
}
|
|
840
|
+
return limit;
|
|
841
|
+
}
|
|
691
842
|
var TraceShipper = class {
|
|
692
843
|
constructor(opts) {
|
|
693
844
|
this.queue = [];
|
|
694
845
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
846
|
+
this.hasShutdown = false;
|
|
695
847
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
696
848
|
this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
|
|
697
849
|
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
@@ -711,6 +863,39 @@ var TraceShipper = class {
|
|
|
711
863
|
}
|
|
712
864
|
this.transformSpanHook = opts.transformSpan;
|
|
713
865
|
this.disableDefaultRedaction = opts.disableDefaultRedaction === true;
|
|
866
|
+
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
870
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
871
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
872
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
873
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
874
|
+
* in the surviving prefix).
|
|
875
|
+
*
|
|
876
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
877
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
878
|
+
*/
|
|
879
|
+
capSpanAttributes(span) {
|
|
880
|
+
var _a;
|
|
881
|
+
const maxChars = applyOtelSpanAttributeLimit(
|
|
882
|
+
resolveMaxTextFieldChars(this.maxTextFieldCharsOpt)
|
|
883
|
+
);
|
|
884
|
+
const attrs = span.attributes;
|
|
885
|
+
if (!attrs || attrs.length === 0) return span;
|
|
886
|
+
let nextAttrs;
|
|
887
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
888
|
+
const attr = attrs[i];
|
|
889
|
+
const value = (_a = attr.value) == null ? void 0 : _a.stringValue;
|
|
890
|
+
if (typeof value !== "string" || value.length <= maxChars) continue;
|
|
891
|
+
if (!nextAttrs) nextAttrs = attrs.slice();
|
|
892
|
+
nextAttrs[i] = {
|
|
893
|
+
key: attr.key,
|
|
894
|
+
value: { ...attr.value, stringValue: capText(value, maxChars) }
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
if (!nextAttrs) return span;
|
|
898
|
+
return { ...span, attributes: nextAttrs };
|
|
714
899
|
}
|
|
715
900
|
/**
|
|
716
901
|
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
@@ -744,7 +929,7 @@ var TraceShipper = class {
|
|
|
744
929
|
if (!this.disableDefaultRedaction) {
|
|
745
930
|
current = defaultTransformSpan(current);
|
|
746
931
|
}
|
|
747
|
-
return current;
|
|
932
|
+
return this.capSpanAttributes(current);
|
|
748
933
|
}
|
|
749
934
|
isDebugEnabled() {
|
|
750
935
|
return this.debug;
|
|
@@ -865,6 +1050,16 @@ var TraceShipper = class {
|
|
|
865
1050
|
while (this.queue.length > 0) {
|
|
866
1051
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
867
1052
|
if (!this.writeKey) continue;
|
|
1053
|
+
const opts = this.requestOpts();
|
|
1054
|
+
if (!opts) {
|
|
1055
|
+
rateLimitedLog(
|
|
1056
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1057
|
+
() => console.warn(
|
|
1058
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1059
|
+
)
|
|
1060
|
+
);
|
|
1061
|
+
continue;
|
|
1062
|
+
}
|
|
868
1063
|
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
869
1064
|
const url = `${this.baseUrl}traces`;
|
|
870
1065
|
if (this.debug) {
|
|
@@ -873,11 +1068,7 @@ var TraceShipper = class {
|
|
|
873
1068
|
endpoint: url
|
|
874
1069
|
});
|
|
875
1070
|
}
|
|
876
|
-
const p = postJson(url, body, this.authHeaders(),
|
|
877
|
-
maxAttempts: 3,
|
|
878
|
-
debug: this.debug,
|
|
879
|
-
sdkName: this.sdkName
|
|
880
|
-
});
|
|
1071
|
+
const p = postJson(url, body, this.authHeaders(), opts);
|
|
881
1072
|
this.inFlight.add(p);
|
|
882
1073
|
try {
|
|
883
1074
|
try {
|
|
@@ -885,21 +1076,61 @@ var TraceShipper = class {
|
|
|
885
1076
|
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
886
1077
|
} catch (err) {
|
|
887
1078
|
const msg = err instanceof Error ? err.message : String(err);
|
|
888
|
-
|
|
1079
|
+
rateLimitedLog(
|
|
1080
|
+
`${this.prefix}.send_spans_failed`,
|
|
1081
|
+
() => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
|
|
1082
|
+
);
|
|
889
1083
|
}
|
|
890
1084
|
} finally {
|
|
891
1085
|
this.inFlight.delete(p);
|
|
892
1086
|
}
|
|
893
1087
|
}
|
|
894
1088
|
}
|
|
1089
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
1090
|
+
requestOpts() {
|
|
1091
|
+
if (this.shutdownDeadlineAt !== void 0) {
|
|
1092
|
+
const remainingMs = this.shutdownDeadlineAt - Date.now();
|
|
1093
|
+
if (remainingMs <= 0) return null;
|
|
1094
|
+
return {
|
|
1095
|
+
maxAttempts: 1,
|
|
1096
|
+
debug: this.debug,
|
|
1097
|
+
sdkName: this.sdkName,
|
|
1098
|
+
timeoutMs: Math.min(DEFAULT_REQUEST_TIMEOUT_MS, remainingMs)
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
if (this.hasShutdown) {
|
|
1102
|
+
return {
|
|
1103
|
+
maxAttempts: 1,
|
|
1104
|
+
debug: this.debug,
|
|
1105
|
+
sdkName: this.sdkName,
|
|
1106
|
+
timeoutMs: POST_SHUTDOWN_TIMEOUT_MS
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
return { maxAttempts: 3, debug: this.debug, sdkName: this.sdkName };
|
|
1110
|
+
}
|
|
895
1111
|
async shutdown() {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1112
|
+
this.hasShutdown = true;
|
|
1113
|
+
this.shutdownDeadlineAt = Date.now() + SHUTDOWN_DEADLINE_MS;
|
|
1114
|
+
try {
|
|
1115
|
+
if (this.timer) {
|
|
1116
|
+
clearTimeout(this.timer);
|
|
1117
|
+
this.timer = void 0;
|
|
1118
|
+
}
|
|
1119
|
+
const drain = async () => {
|
|
1120
|
+
await this.flush();
|
|
1121
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1122
|
+
})));
|
|
1123
|
+
};
|
|
1124
|
+
const settled = await raceWithTimeout(drain(), SHUTDOWN_DEADLINE_MS);
|
|
1125
|
+
if (!settled) {
|
|
1126
|
+
rateLimitedLog(
|
|
1127
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1128
|
+
() => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
} finally {
|
|
1132
|
+
this.shutdownDeadlineAt = void 0;
|
|
899
1133
|
}
|
|
900
|
-
await this.flush();
|
|
901
|
-
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
902
|
-
})));
|
|
903
1134
|
}
|
|
904
1135
|
};
|
|
905
1136
|
var NOOP_SPAN = {
|
|
@@ -1024,7 +1255,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
|
|
|
1024
1255
|
// package.json
|
|
1025
1256
|
var package_default = {
|
|
1026
1257
|
name: "@raindrop-ai/ai-sdk",
|
|
1027
|
-
version: "0.0.
|
|
1258
|
+
version: "0.0.34"};
|
|
1028
1259
|
|
|
1029
1260
|
// src/internal/version.ts
|
|
1030
1261
|
var libraryName = package_default.name;
|
|
@@ -1043,6 +1274,133 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1043
1274
|
}
|
|
1044
1275
|
};
|
|
1045
1276
|
|
|
1277
|
+
// src/internal/truncation.ts
|
|
1278
|
+
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
1279
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
|
|
1280
|
+
var MAX_DEPTH = 12;
|
|
1281
|
+
var configuredMaxTextFieldChars;
|
|
1282
|
+
function setMaxTextFieldChars(limit) {
|
|
1283
|
+
if (limit === void 0) return;
|
|
1284
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
1285
|
+
configuredMaxTextFieldChars = Math.floor(limit);
|
|
1286
|
+
} else {
|
|
1287
|
+
console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
function otelEnvLimit() {
|
|
1291
|
+
var _a;
|
|
1292
|
+
if (typeof process === "undefined") return void 0;
|
|
1293
|
+
const raw = (_a = process.env) == null ? void 0 : _a.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
1294
|
+
if (!raw) return void 0;
|
|
1295
|
+
const parsed = Number.parseInt(raw, 10);
|
|
1296
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1297
|
+
}
|
|
1298
|
+
function effectiveMaxTextFieldChars() {
|
|
1299
|
+
const base = configuredMaxTextFieldChars != null ? configuredMaxTextFieldChars : DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
1300
|
+
const env = otelEnvLimit();
|
|
1301
|
+
return env !== void 0 && env < base ? env : base;
|
|
1302
|
+
}
|
|
1303
|
+
function truncateToLimit2(text, limit) {
|
|
1304
|
+
if (limit > TRUNCATION_MARKER2.length) {
|
|
1305
|
+
return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
|
|
1306
|
+
}
|
|
1307
|
+
return text.slice(0, limit);
|
|
1308
|
+
}
|
|
1309
|
+
function capText2(value, limit) {
|
|
1310
|
+
if (typeof value !== "string") return value;
|
|
1311
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1312
|
+
if (value.length <= max) return value;
|
|
1313
|
+
return truncateToLimit2(value, max);
|
|
1314
|
+
}
|
|
1315
|
+
function boundedClone2(value, budget, depth) {
|
|
1316
|
+
var _a, _b;
|
|
1317
|
+
if (budget.remaining <= 0) return TRUNCATION_MARKER2;
|
|
1318
|
+
if (typeof value === "string") {
|
|
1319
|
+
if (value.length > budget.remaining) {
|
|
1320
|
+
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1321
|
+
budget.remaining = 0;
|
|
1322
|
+
return taken;
|
|
1323
|
+
}
|
|
1324
|
+
budget.remaining -= Math.max(value.length, 1);
|
|
1325
|
+
return value;
|
|
1326
|
+
}
|
|
1327
|
+
if (value === null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1328
|
+
budget.remaining -= 8;
|
|
1329
|
+
return value;
|
|
1330
|
+
}
|
|
1331
|
+
if (typeof value !== "object") {
|
|
1332
|
+
budget.remaining -= 1;
|
|
1333
|
+
return value;
|
|
1334
|
+
}
|
|
1335
|
+
if (value instanceof Uint8Array) {
|
|
1336
|
+
const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
|
|
1337
|
+
if (value.byteLength > maxBytes) {
|
|
1338
|
+
const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
|
|
1339
|
+
budget.remaining = 0;
|
|
1340
|
+
return taken;
|
|
1341
|
+
}
|
|
1342
|
+
const encoded = base64Encode(value);
|
|
1343
|
+
budget.remaining -= Math.max(encoded.length, 1);
|
|
1344
|
+
return encoded;
|
|
1345
|
+
}
|
|
1346
|
+
if (depth >= MAX_DEPTH) {
|
|
1347
|
+
budget.remaining -= 16;
|
|
1348
|
+
const name = (_b = (_a = value.constructor) == null ? void 0 : _a.name) != null ? _b : "object";
|
|
1349
|
+
return `<max depth: ${name}>`;
|
|
1350
|
+
}
|
|
1351
|
+
const toJSON = value.toJSON;
|
|
1352
|
+
if (typeof toJSON === "function") {
|
|
1353
|
+
budget.remaining -= 2;
|
|
1354
|
+
return boundedClone2(toJSON.call(value), budget, depth + 1);
|
|
1355
|
+
}
|
|
1356
|
+
if (Array.isArray(value)) {
|
|
1357
|
+
budget.remaining -= 2;
|
|
1358
|
+
const out2 = [];
|
|
1359
|
+
for (const item of value) {
|
|
1360
|
+
if (budget.remaining <= 0) {
|
|
1361
|
+
out2.push(TRUNCATION_MARKER2);
|
|
1362
|
+
break;
|
|
1363
|
+
}
|
|
1364
|
+
out2.push(boundedClone2(item, budget, depth + 1));
|
|
1365
|
+
}
|
|
1366
|
+
return out2;
|
|
1367
|
+
}
|
|
1368
|
+
budget.remaining -= 2;
|
|
1369
|
+
const out = {};
|
|
1370
|
+
for (const key in value) {
|
|
1371
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
1372
|
+
if (budget.remaining <= 0) {
|
|
1373
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
1374
|
+
break;
|
|
1375
|
+
}
|
|
1376
|
+
let cappedKey = key;
|
|
1377
|
+
if (key.length > budget.remaining) {
|
|
1378
|
+
cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
1379
|
+
budget.remaining = 0;
|
|
1380
|
+
out[cappedKey] = TRUNCATION_MARKER2;
|
|
1381
|
+
break;
|
|
1382
|
+
}
|
|
1383
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
1384
|
+
out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
|
|
1385
|
+
}
|
|
1386
|
+
return out;
|
|
1387
|
+
}
|
|
1388
|
+
function boundedStringify(value, limit) {
|
|
1389
|
+
const max = limit != null ? limit : effectiveMaxTextFieldChars();
|
|
1390
|
+
try {
|
|
1391
|
+
if (typeof value === "string") {
|
|
1392
|
+
const text2 = JSON.stringify(capText2(value, max));
|
|
1393
|
+
return text2.length <= max ? text2 : truncateToLimit2(text2, max);
|
|
1394
|
+
}
|
|
1395
|
+
const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
1396
|
+
const text = JSON.stringify(pruned);
|
|
1397
|
+
if (text === void 0) return void 0;
|
|
1398
|
+
return text.length <= max ? text : truncateToLimit2(text, max);
|
|
1399
|
+
} catch (e) {
|
|
1400
|
+
return void 0;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1046
1404
|
// src/internal/wrap/helpers.ts
|
|
1047
1405
|
function isRecord(value) {
|
|
1048
1406
|
return typeof value === "object" && value !== null;
|
|
@@ -1067,21 +1425,10 @@ function isModuleNamespace(obj) {
|
|
|
1067
1425
|
}
|
|
1068
1426
|
}
|
|
1069
1427
|
function safeJson(value) {
|
|
1070
|
-
|
|
1071
|
-
return JSON.stringify(value);
|
|
1072
|
-
} catch (e) {
|
|
1073
|
-
return void 0;
|
|
1074
|
-
}
|
|
1428
|
+
return boundedStringify(value);
|
|
1075
1429
|
}
|
|
1076
1430
|
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
|
-
}
|
|
1431
|
+
return boundedStringify(value);
|
|
1085
1432
|
}
|
|
1086
1433
|
function extractModelInfo(model) {
|
|
1087
1434
|
if (typeof model === "string") {
|
|
@@ -1977,7 +2324,10 @@ var RaindropTelemetryIntegration = class {
|
|
|
1977
2324
|
inputAttrs.push(
|
|
1978
2325
|
attrStringArray(
|
|
1979
2326
|
"ai.prompt.tools",
|
|
1980
|
-
event.stepTools.map((t) =>
|
|
2327
|
+
event.stepTools.map((t) => {
|
|
2328
|
+
var _a;
|
|
2329
|
+
return (_a = safeJsonWithUint8(t)) != null ? _a : "";
|
|
2330
|
+
})
|
|
1981
2331
|
)
|
|
1982
2332
|
);
|
|
1983
2333
|
}
|
|
@@ -1985,7 +2335,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
1985
2335
|
inputAttrs.push(
|
|
1986
2336
|
attrString(
|
|
1987
2337
|
"ai.prompt.toolChoice",
|
|
1988
|
-
|
|
2338
|
+
safeJsonWithUint8(event.stepToolChoice)
|
|
1989
2339
|
)
|
|
1990
2340
|
);
|
|
1991
2341
|
}
|
|
@@ -2041,7 +2391,9 @@ var RaindropTelemetryIntegration = class {
|
|
|
2041
2391
|
if (chunk.type === "text-delta") {
|
|
2042
2392
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
2043
2393
|
if (typeof delta === "string") {
|
|
2044
|
-
state.accumulatedText
|
|
2394
|
+
if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
|
|
2395
|
+
state.accumulatedText += delta;
|
|
2396
|
+
}
|
|
2045
2397
|
this.emitLive(state, "text_delta", delta);
|
|
2046
2398
|
}
|
|
2047
2399
|
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
@@ -2060,7 +2412,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2060
2412
|
if (state.recordOutputs) {
|
|
2061
2413
|
outputAttrs.push(
|
|
2062
2414
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2063
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2415
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2064
2416
|
attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
|
|
2065
2417
|
attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
|
|
2066
2418
|
attrString(
|
|
@@ -2076,7 +2428,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2076
2428
|
outputAttrs.push(
|
|
2077
2429
|
attrString(
|
|
2078
2430
|
"ai.response.toolCalls",
|
|
2079
|
-
|
|
2431
|
+
safeJsonWithUint8(
|
|
2080
2432
|
event.toolCalls.map((tc) => ({
|
|
2081
2433
|
toolCallId: tc.toolCallId,
|
|
2082
2434
|
toolName: tc.toolName,
|
|
@@ -2089,7 +2441,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2089
2441
|
if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
|
|
2090
2442
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2091
2443
|
if (reasoningText) {
|
|
2092
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2444
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2093
2445
|
}
|
|
2094
2446
|
}
|
|
2095
2447
|
}
|
|
@@ -2511,7 +2863,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2511
2863
|
if (state.recordOutputs) {
|
|
2512
2864
|
outputAttrs.push(
|
|
2513
2865
|
attrString("ai.response.finishReason", event.finishReason),
|
|
2514
|
-
attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
|
|
2866
|
+
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
2515
2867
|
attrString(
|
|
2516
2868
|
"ai.response.providerMetadata",
|
|
2517
2869
|
event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
|
|
@@ -2521,7 +2873,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2521
2873
|
outputAttrs.push(
|
|
2522
2874
|
attrString(
|
|
2523
2875
|
"ai.response.toolCalls",
|
|
2524
|
-
|
|
2876
|
+
safeJsonWithUint8(
|
|
2525
2877
|
event.toolCalls.map((tc) => ({
|
|
2526
2878
|
toolCallId: tc.toolCallId,
|
|
2527
2879
|
toolName: tc.toolName,
|
|
@@ -2534,7 +2886,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2534
2886
|
if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
|
|
2535
2887
|
const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
|
|
2536
2888
|
if (reasoningText) {
|
|
2537
|
-
outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
|
|
2889
|
+
outputAttrs.push(attrString("ai.response.reasoning", capText2(reasoningText)));
|
|
2538
2890
|
}
|
|
2539
2891
|
}
|
|
2540
2892
|
}
|
|
@@ -2572,7 +2924,8 @@ var RaindropTelemetryIntegration = class {
|
|
|
2572
2924
|
const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
|
|
2573
2925
|
if (!userId) return;
|
|
2574
2926
|
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
|
|
2575
|
-
const
|
|
2927
|
+
const cappedOutput = capText2(output);
|
|
2928
|
+
const input = capText2(state.inputText);
|
|
2576
2929
|
const properties = {
|
|
2577
2930
|
...(_f = this.defaultContext) == null ? void 0 : _f.properties,
|
|
2578
2931
|
...callMeta.properties
|
|
@@ -2583,7 +2936,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
2583
2936
|
userId,
|
|
2584
2937
|
convoId,
|
|
2585
2938
|
input,
|
|
2586
|
-
output,
|
|
2939
|
+
output: cappedOutput,
|
|
2587
2940
|
model,
|
|
2588
2941
|
properties: Object.keys(properties).length > 0 ? properties : void 0,
|
|
2589
2942
|
isPending: false
|
|
@@ -3056,13 +3409,14 @@ function shouldKeepEventPending(params) {
|
|
|
3056
3409
|
return params.finishReason === "tool-calls" || params.finishReason === "tool_calls";
|
|
3057
3410
|
}
|
|
3058
3411
|
function normalizePromptAttr(arg) {
|
|
3412
|
+
var _a, _b;
|
|
3059
3413
|
if (!isRecord(arg)) return arg;
|
|
3060
3414
|
const system = arg["system"];
|
|
3061
3415
|
const prompt = arg["prompt"];
|
|
3062
3416
|
const messages = arg["messages"];
|
|
3063
3417
|
if (Array.isArray(messages)) {
|
|
3064
3418
|
if (system) {
|
|
3065
|
-
const sysContent = typeof system === "string" ? system :
|
|
3419
|
+
const sysContent = typeof system === "string" ? system : (_a = safeJsonWithUint8(system)) != null ? _a : String(system);
|
|
3066
3420
|
return [{ role: "system", content: sysContent }, ...messages];
|
|
3067
3421
|
}
|
|
3068
3422
|
return messages;
|
|
@@ -3070,7 +3424,10 @@ function normalizePromptAttr(arg) {
|
|
|
3070
3424
|
if (typeof prompt === "string") {
|
|
3071
3425
|
const msgs = [];
|
|
3072
3426
|
if (system) {
|
|
3073
|
-
msgs.push({
|
|
3427
|
+
msgs.push({
|
|
3428
|
+
role: "system",
|
|
3429
|
+
content: typeof system === "string" ? system : (_b = safeJsonWithUint8(system)) != null ? _b : String(system)
|
|
3430
|
+
});
|
|
3074
3431
|
}
|
|
3075
3432
|
msgs.push({ role: "user", content: prompt });
|
|
3076
3433
|
return msgs;
|
|
@@ -3239,7 +3596,8 @@ function createFinalize(params) {
|
|
|
3239
3596
|
};
|
|
3240
3597
|
const built = await maybeBuildEvent(options.buildEvent, allMessages);
|
|
3241
3598
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3242
|
-
const output = patch.output;
|
|
3599
|
+
const output = capText2(patch.output);
|
|
3600
|
+
const input = capText2(patch.input);
|
|
3243
3601
|
const finalModel = (_c = patch.model) != null ? _c : model;
|
|
3244
3602
|
if (setup.rootSpan) {
|
|
3245
3603
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3283,7 +3641,7 @@ function createFinalize(params) {
|
|
|
3283
3641
|
eventName: patch.eventName,
|
|
3284
3642
|
userId: setup.ctx.userId,
|
|
3285
3643
|
convoId: setup.ctx.convoId,
|
|
3286
|
-
input
|
|
3644
|
+
input,
|
|
3287
3645
|
output,
|
|
3288
3646
|
model: finalModel,
|
|
3289
3647
|
properties: patch.properties,
|
|
@@ -3798,7 +4156,8 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3798
4156
|
};
|
|
3799
4157
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
3800
4158
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
3801
|
-
const output = patch.output;
|
|
4159
|
+
const output = capText2(patch.output);
|
|
4160
|
+
const input = capText2(patch.input);
|
|
3802
4161
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
3803
4162
|
if (rootSpan) {
|
|
3804
4163
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -3856,7 +4215,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
3856
4215
|
eventName: patch.eventName,
|
|
3857
4216
|
userId: ctx.userId,
|
|
3858
4217
|
convoId: ctx.convoId,
|
|
3859
|
-
input
|
|
4218
|
+
input,
|
|
3860
4219
|
output,
|
|
3861
4220
|
model: finalModel,
|
|
3862
4221
|
properties: patch.properties,
|
|
@@ -4005,7 +4364,8 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4005
4364
|
};
|
|
4006
4365
|
const built = await maybeBuildEvent(deps.options.buildEvent, allMessages);
|
|
4007
4366
|
const patch = mergeBuildEventPatch(defaultPatch, built);
|
|
4008
|
-
const output = patch.output;
|
|
4367
|
+
const output = capText2(patch.output);
|
|
4368
|
+
const input = capText2(patch.input);
|
|
4009
4369
|
const finalModel = (_c2 = patch.model) != null ? _c2 : model;
|
|
4010
4370
|
if (rootSpan) {
|
|
4011
4371
|
const spanEndTimeUnixNano = nowUnixNanoString();
|
|
@@ -4063,7 +4423,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
4063
4423
|
eventName: patch.eventName,
|
|
4064
4424
|
userId: ctx.userId,
|
|
4065
4425
|
convoId: ctx.convoId,
|
|
4066
|
-
input
|
|
4426
|
+
input,
|
|
4067
4427
|
output,
|
|
4068
4428
|
model: finalModel,
|
|
4069
4429
|
properties: patch.properties,
|
|
@@ -4403,7 +4763,7 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4403
4763
|
attributes: [
|
|
4404
4764
|
...((_a = ctx.telemetry) == null ? void 0 : _a.recordOutputs) === false ? [] : [
|
|
4405
4765
|
attrString("ai.response.finishReason", finishReason),
|
|
4406
|
-
attrString("ai.response.text", activeText.length ? activeText : void 0),
|
|
4766
|
+
attrString("ai.response.text", activeText.length ? capText2(activeText) : void 0),
|
|
4407
4767
|
attrString(
|
|
4408
4768
|
"ai.response.toolCalls",
|
|
4409
4769
|
safeJsonWithUint8(toolCallsLocal.length ? toolCallsLocal : void 0)
|
|
@@ -4456,7 +4816,9 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
|
|
|
4456
4816
|
} else if (typeof value["textDelta"] === "string") {
|
|
4457
4817
|
textDelta = value["textDelta"];
|
|
4458
4818
|
}
|
|
4459
|
-
if (typeof textDelta === "string"
|
|
4819
|
+
if (typeof textDelta === "string" && activeText.length <= effectiveMaxTextFieldChars()) {
|
|
4820
|
+
activeText += textDelta;
|
|
4821
|
+
}
|
|
4460
4822
|
}
|
|
4461
4823
|
if (type === "finish") finishReason = extractFinishReason(value);
|
|
4462
4824
|
if (type === "tool-call") toolCallsLocal.push(value);
|
|
@@ -4729,8 +5091,8 @@ function eventMetadataFromChatRequest(options) {
|
|
|
4729
5091
|
});
|
|
4730
5092
|
}
|
|
4731
5093
|
function stringify(v) {
|
|
4732
|
-
if (typeof v === "string") return v;
|
|
4733
|
-
return
|
|
5094
|
+
if (typeof v === "string") return capText2(v);
|
|
5095
|
+
return boundedStringify(v);
|
|
4734
5096
|
}
|
|
4735
5097
|
function userAttrsToOtlp(attrs) {
|
|
4736
5098
|
if (!attrs) return [];
|
|
@@ -4748,6 +5110,7 @@ function createRaindropAISDK(opts) {
|
|
|
4748
5110
|
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
4749
5111
|
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
4750
5112
|
const envDebug = envDebugEnabled();
|
|
5113
|
+
setMaxTextFieldChars(opts.maxTextFieldChars);
|
|
4751
5114
|
const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
|
|
4752
5115
|
const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
|
|
4753
5116
|
const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
|
|
@@ -4939,13 +5302,17 @@ if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
|
|
|
4939
5302
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
|
|
4940
5303
|
}
|
|
4941
5304
|
|
|
5305
|
+
exports.DEFAULT_MAX_TEXT_FIELD_CHARS = DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
4942
5306
|
exports.DEFAULT_REDACT_ATTRIBUTE_KEYS = DEFAULT_REDACT_ATTRIBUTE_KEYS;
|
|
4943
5307
|
exports.DEFAULT_SECRET_KEY_NAMES = DEFAULT_SECRET_KEY_NAMES;
|
|
4944
5308
|
exports.REDACTED_PLACEHOLDER = REDACTED_PLACEHOLDER;
|
|
4945
5309
|
exports.RaindropTelemetryIntegration = RaindropTelemetryIntegration;
|
|
5310
|
+
exports.TRUNCATION_MARKER = TRUNCATION_MARKER2;
|
|
4946
5311
|
exports._resetParentToolContextStorage = _resetParentToolContextStorage;
|
|
4947
5312
|
exports._resetRaindropCallMetadataStorage = _resetRaindropCallMetadataStorage;
|
|
4948
5313
|
exports._resetWarnedMissingUserId = _resetWarnedMissingUserId;
|
|
5314
|
+
exports.boundedStringify = boundedStringify;
|
|
5315
|
+
exports.capText = capText2;
|
|
4949
5316
|
exports.clearParentToolContext = clearParentToolContext;
|
|
4950
5317
|
exports.createRaindropAISDK = createRaindropAISDK;
|
|
4951
5318
|
exports.currentSpan = currentSpan;
|