@raindrop-ai/deep-agents 0.0.1 → 0.0.2
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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/index.d.mts +155 -2
- package/dist/index.d.ts +155 -2
- package/dist/index.js +586 -96
- package/dist/index.mjs +586 -96
- package/package.json +10 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Raindrop AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ The `createRaindropDeepAgents()` factory returns:
|
|
|
97
97
|
- **Streaming**: Token-by-token streaming events are not captured individually; only the final aggregated response is tracked.
|
|
98
98
|
- **Subagent isolation**: When using the `task` tool for subagent delegation, each subagent's callbacks fire independently.
|
|
99
99
|
- **Concurrent invocations on a shared handler**: A single handler instance keeps one in-flight span map at a time. Running multiple `agent.invoke(...)` calls **concurrently with the same handler** (e.g. `Promise.all([agent.invoke(...), agent.invoke(...)])` with the same `raindrop.handler`) can scramble the linkage between events and traces. Instantiate one `createRaindropDeepAgents()` per concurrent request; sequential invocations on a shared handler are fully supported.
|
|
100
|
-
- **Long chain inputs/outputs are truncated**: Chain-level `input` and `output` captured on the root event are truncated to ~8 KB to stay within the SDK's payload-size limit. Per-LLM child events still carry full prompts.
|
|
100
|
+
- **Long chain inputs/outputs are truncated**: Chain-level `input` and `output` captured on the root event are truncated to ~8 KB to stay within the SDK's payload-size limit. Per-LLM child events still carry full prompts. Tool payloads are pruned to their cap _before_ JSON serialization, so a multi-MB tool output costs the cap — not the payload — on your event loop (truncated values carry a `...[truncated by raindrop]` marker).
|
|
101
101
|
|
|
102
102
|
## Testing
|
|
103
103
|
|
package/dist/index.d.mts
CHANGED
|
@@ -42,7 +42,6 @@ type SpanIds = {
|
|
|
42
42
|
spanIdB64: string;
|
|
43
43
|
parentSpanIdB64?: string;
|
|
44
44
|
};
|
|
45
|
-
|
|
46
45
|
type Attachment = {
|
|
47
46
|
type: string;
|
|
48
47
|
role: string;
|
|
@@ -86,6 +85,19 @@ type EventShipperOptions = {
|
|
|
86
85
|
libraryName?: string;
|
|
87
86
|
libraryVersion?: string;
|
|
88
87
|
defaultEventName?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
90
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
91
|
+
*/
|
|
92
|
+
localDebuggerUrl?: string | null;
|
|
93
|
+
/**
|
|
94
|
+
* Per-field character cap applied to event input/output BEFORE buffering
|
|
95
|
+
* or serialization, so oversized payloads cost the cap — not the payload —
|
|
96
|
+
* on the calling code path. Truncated fields end with
|
|
97
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
98
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
99
|
+
*/
|
|
100
|
+
maxTextFieldChars?: number;
|
|
89
101
|
};
|
|
90
102
|
declare class EventShipper {
|
|
91
103
|
private baseUrl;
|
|
@@ -101,9 +113,39 @@ declare class EventShipper {
|
|
|
101
113
|
private sticky;
|
|
102
114
|
private timers;
|
|
103
115
|
private inFlight;
|
|
116
|
+
private maxTextFieldCharsOpt;
|
|
117
|
+
/**
|
|
118
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
119
|
+
* Checked before every POST issued during the final flush.
|
|
120
|
+
*/
|
|
121
|
+
private shutdownDeadlineAt;
|
|
122
|
+
/**
|
|
123
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
124
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
125
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
126
|
+
* retry schedule.
|
|
127
|
+
*/
|
|
128
|
+
private hasShutdown;
|
|
129
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
130
|
+
private localDebuggerUrl;
|
|
104
131
|
constructor(opts: EventShipperOptions);
|
|
105
132
|
isDebugEnabled(): boolean;
|
|
106
133
|
private authHeaders;
|
|
134
|
+
/**
|
|
135
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
136
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
137
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
138
|
+
* of issuing a request that could outlive process exit.
|
|
139
|
+
*
|
|
140
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
141
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
142
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
143
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
144
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
145
|
+
* run as a single short attempt rather than regaining the full retry
|
|
146
|
+
* schedule.
|
|
147
|
+
*/
|
|
148
|
+
private requestOpts;
|
|
107
149
|
patch(eventId: string, patch: Patch): Promise<void>;
|
|
108
150
|
finish(eventId: string, patch: {
|
|
109
151
|
output?: string;
|
|
@@ -115,8 +157,26 @@ declare class EventShipper {
|
|
|
115
157
|
shutdown(): Promise<void>;
|
|
116
158
|
trackSignal(signal: SignalInput): Promise<void>;
|
|
117
159
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
160
|
+
private warnShutdownDrop;
|
|
118
161
|
private flushOne;
|
|
119
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Hook fired per OTLP span right before the span is shipped (to the Raindrop
|
|
165
|
+
* API and to a local debugger). Lets callers inspect, rewrite, or drop the
|
|
166
|
+
* entire span — not just individual attributes — which is more flexible than
|
|
167
|
+
* an attribute-level hook (you can rename attributes, add new ones, drop the
|
|
168
|
+
* span outright, etc.).
|
|
169
|
+
*
|
|
170
|
+
* Return values:
|
|
171
|
+
* - `undefined` or the same span: ship the span unchanged.
|
|
172
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
173
|
+
* - `null`: drop the span entirely from every ship path.
|
|
174
|
+
*
|
|
175
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
176
|
+
* If the hook throws, the span is dropped (fail-closed) so a buggy hook can
|
|
177
|
+
* never accidentally ship raw, un-redacted spans.
|
|
178
|
+
*/
|
|
179
|
+
type TransformSpanHook = (span: OtlpSpan) => OtlpSpan | null | undefined;
|
|
120
180
|
|
|
121
181
|
type InternalSpan = {
|
|
122
182
|
ids: SpanIds;
|
|
@@ -137,6 +197,54 @@ type TraceShipperOptions = {
|
|
|
137
197
|
sdkName?: string;
|
|
138
198
|
serviceName?: string;
|
|
139
199
|
serviceVersion?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
202
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
203
|
+
*/
|
|
204
|
+
localDebuggerUrl?: string | null;
|
|
205
|
+
/**
|
|
206
|
+
* Per-span hook that fires for every OTLP span right before the span is
|
|
207
|
+
* shipped (both to the Raindrop API and to a local debugger). Lets callers
|
|
208
|
+
* inspect, rewrite, or drop entire spans — rename attributes, add new ones,
|
|
209
|
+
* scrub additional secret-shaped values inside `ai.prompt.messages` /
|
|
210
|
+
* `ai.toolCall.args`, etc.
|
|
211
|
+
*
|
|
212
|
+
* Return values:
|
|
213
|
+
* - `undefined` or the same span reference: ship the span unchanged.
|
|
214
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
215
|
+
* - `null`: drop the span entirely from every ship path.
|
|
216
|
+
*
|
|
217
|
+
* The hook runs BEFORE the default redactor (which is the always-on floor
|
|
218
|
+
* for documented BYOK secrets). The default redactor still runs on the
|
|
219
|
+
* post-transform span unless `disableDefaultRedaction` is set, so even if
|
|
220
|
+
* a custom transform overlooks a secret-shaped attribute, the floor catches
|
|
221
|
+
* it.
|
|
222
|
+
*
|
|
223
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
224
|
+
* If the hook itself throws, the span is dropped (fail-closed) so a buggy
|
|
225
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
226
|
+
*/
|
|
227
|
+
transformSpan?: TransformSpanHook;
|
|
228
|
+
/**
|
|
229
|
+
* Disable the built-in default span transformer (which scrubs documented
|
|
230
|
+
* secret-shaped properties — `apiKey`, `secretAccessKey`, `privateKey`,
|
|
231
|
+
* etc. — inside `ai.request.providerOptions` and
|
|
232
|
+
* `ai.response.providerMetadata`).
|
|
233
|
+
*
|
|
234
|
+
* Default: `false` (i.e. default redaction is on). Setting this to `true`
|
|
235
|
+
* disables the floor entirely; provide a custom `transformSpan` if you
|
|
236
|
+
* still want some redaction in that case.
|
|
237
|
+
*/
|
|
238
|
+
disableDefaultRedaction?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Per-attribute character cap applied to every span attribute string value
|
|
241
|
+
* right before the span enters a ship path, so a multi-MB prompt/tool
|
|
242
|
+
* payload can never make the batch `JSON.stringify` (which runs on the
|
|
243
|
+
* event loop) cost seconds. Truncated values end with
|
|
244
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
245
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
246
|
+
*/
|
|
247
|
+
maxTextFieldChars?: number;
|
|
140
248
|
};
|
|
141
249
|
declare class TraceShipper {
|
|
142
250
|
private baseUrl;
|
|
@@ -154,9 +262,51 @@ declare class TraceShipper {
|
|
|
154
262
|
private queue;
|
|
155
263
|
private timer;
|
|
156
264
|
private inFlight;
|
|
157
|
-
/** URL of the local debugger
|
|
265
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
158
266
|
private localDebuggerUrl;
|
|
267
|
+
private transformSpanHook;
|
|
268
|
+
private disableDefaultRedaction;
|
|
269
|
+
private maxTextFieldCharsOpt;
|
|
270
|
+
/**
|
|
271
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
272
|
+
* Checked before every batch POST issued during the final flush.
|
|
273
|
+
*/
|
|
274
|
+
private shutdownDeadlineAt;
|
|
275
|
+
/**
|
|
276
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
277
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
278
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
279
|
+
* retry schedule.
|
|
280
|
+
*/
|
|
281
|
+
private hasShutdown;
|
|
159
282
|
constructor(opts: TraceShipperOptions);
|
|
283
|
+
/**
|
|
284
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
285
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
286
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
287
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
288
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
289
|
+
* in the surviving prefix).
|
|
290
|
+
*
|
|
291
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
292
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
293
|
+
*/
|
|
294
|
+
private capSpanAttributes;
|
|
295
|
+
/**
|
|
296
|
+
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
297
|
+
* redactor (unless disabled). Returns either the (possibly new) span to
|
|
298
|
+
* ship, or `null` to drop the span entirely.
|
|
299
|
+
*
|
|
300
|
+
* Ordering: user hook runs first so callers can rewrite the span freely
|
|
301
|
+
* (rename attrs, add new ones, scrub things the default doesn't know
|
|
302
|
+
* about). The default redactor then runs on whatever the user produced,
|
|
303
|
+
* acting as the always-on floor for documented BYOK secrets. If the user
|
|
304
|
+
* sets `disableDefaultRedaction: true`, the floor is skipped.
|
|
305
|
+
*
|
|
306
|
+
* Fail-closed: if the user hook throws, the span is dropped — a buggy
|
|
307
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
308
|
+
*/
|
|
309
|
+
private redactSpan;
|
|
160
310
|
isDebugEnabled(): boolean;
|
|
161
311
|
private authHeaders;
|
|
162
312
|
startSpan(args: {
|
|
@@ -170,6 +320,7 @@ declare class TraceShipper {
|
|
|
170
320
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
171
321
|
startTimeUnixNano?: string;
|
|
172
322
|
}): InternalSpan;
|
|
323
|
+
private mirrorToLocalDebugger;
|
|
173
324
|
endSpan(span: InternalSpan, extra?: {
|
|
174
325
|
attributes?: InternalSpan["attributes"];
|
|
175
326
|
error?: unknown;
|
|
@@ -190,6 +341,8 @@ declare class TraceShipper {
|
|
|
190
341
|
}): void;
|
|
191
342
|
enqueue(span: OtlpSpan): void;
|
|
192
343
|
flush(): Promise<void>;
|
|
344
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
345
|
+
private requestOpts;
|
|
193
346
|
shutdown(): Promise<void>;
|
|
194
347
|
}
|
|
195
348
|
|
package/dist/index.d.ts
CHANGED
|
@@ -42,7 +42,6 @@ type SpanIds = {
|
|
|
42
42
|
spanIdB64: string;
|
|
43
43
|
parentSpanIdB64?: string;
|
|
44
44
|
};
|
|
45
|
-
|
|
46
45
|
type Attachment = {
|
|
47
46
|
type: string;
|
|
48
47
|
role: string;
|
|
@@ -86,6 +85,19 @@ type EventShipperOptions = {
|
|
|
86
85
|
libraryName?: string;
|
|
87
86
|
libraryVersion?: string;
|
|
88
87
|
defaultEventName?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
90
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
91
|
+
*/
|
|
92
|
+
localDebuggerUrl?: string | null;
|
|
93
|
+
/**
|
|
94
|
+
* Per-field character cap applied to event input/output BEFORE buffering
|
|
95
|
+
* or serialization, so oversized payloads cost the cap — not the payload —
|
|
96
|
+
* on the calling code path. Truncated fields end with
|
|
97
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
98
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
99
|
+
*/
|
|
100
|
+
maxTextFieldChars?: number;
|
|
89
101
|
};
|
|
90
102
|
declare class EventShipper {
|
|
91
103
|
private baseUrl;
|
|
@@ -101,9 +113,39 @@ declare class EventShipper {
|
|
|
101
113
|
private sticky;
|
|
102
114
|
private timers;
|
|
103
115
|
private inFlight;
|
|
116
|
+
private maxTextFieldCharsOpt;
|
|
117
|
+
/**
|
|
118
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
119
|
+
* Checked before every POST issued during the final flush.
|
|
120
|
+
*/
|
|
121
|
+
private shutdownDeadlineAt;
|
|
122
|
+
/**
|
|
123
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
124
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
125
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
126
|
+
* retry schedule.
|
|
127
|
+
*/
|
|
128
|
+
private hasShutdown;
|
|
129
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
130
|
+
private localDebuggerUrl;
|
|
104
131
|
constructor(opts: EventShipperOptions);
|
|
105
132
|
isDebugEnabled(): boolean;
|
|
106
133
|
private authHeaders;
|
|
134
|
+
/**
|
|
135
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
136
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
137
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
138
|
+
* of issuing a request that could outlive process exit.
|
|
139
|
+
*
|
|
140
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
141
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
142
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
143
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
144
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
145
|
+
* run as a single short attempt rather than regaining the full retry
|
|
146
|
+
* schedule.
|
|
147
|
+
*/
|
|
148
|
+
private requestOpts;
|
|
107
149
|
patch(eventId: string, patch: Patch): Promise<void>;
|
|
108
150
|
finish(eventId: string, patch: {
|
|
109
151
|
output?: string;
|
|
@@ -115,8 +157,26 @@ declare class EventShipper {
|
|
|
115
157
|
shutdown(): Promise<void>;
|
|
116
158
|
trackSignal(signal: SignalInput): Promise<void>;
|
|
117
159
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
160
|
+
private warnShutdownDrop;
|
|
118
161
|
private flushOne;
|
|
119
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Hook fired per OTLP span right before the span is shipped (to the Raindrop
|
|
165
|
+
* API and to a local debugger). Lets callers inspect, rewrite, or drop the
|
|
166
|
+
* entire span — not just individual attributes — which is more flexible than
|
|
167
|
+
* an attribute-level hook (you can rename attributes, add new ones, drop the
|
|
168
|
+
* span outright, etc.).
|
|
169
|
+
*
|
|
170
|
+
* Return values:
|
|
171
|
+
* - `undefined` or the same span: ship the span unchanged.
|
|
172
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
173
|
+
* - `null`: drop the span entirely from every ship path.
|
|
174
|
+
*
|
|
175
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
176
|
+
* If the hook throws, the span is dropped (fail-closed) so a buggy hook can
|
|
177
|
+
* never accidentally ship raw, un-redacted spans.
|
|
178
|
+
*/
|
|
179
|
+
type TransformSpanHook = (span: OtlpSpan) => OtlpSpan | null | undefined;
|
|
120
180
|
|
|
121
181
|
type InternalSpan = {
|
|
122
182
|
ids: SpanIds;
|
|
@@ -137,6 +197,54 @@ type TraceShipperOptions = {
|
|
|
137
197
|
sdkName?: string;
|
|
138
198
|
serviceName?: string;
|
|
139
199
|
serviceVersion?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
202
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
203
|
+
*/
|
|
204
|
+
localDebuggerUrl?: string | null;
|
|
205
|
+
/**
|
|
206
|
+
* Per-span hook that fires for every OTLP span right before the span is
|
|
207
|
+
* shipped (both to the Raindrop API and to a local debugger). Lets callers
|
|
208
|
+
* inspect, rewrite, or drop entire spans — rename attributes, add new ones,
|
|
209
|
+
* scrub additional secret-shaped values inside `ai.prompt.messages` /
|
|
210
|
+
* `ai.toolCall.args`, etc.
|
|
211
|
+
*
|
|
212
|
+
* Return values:
|
|
213
|
+
* - `undefined` or the same span reference: ship the span unchanged.
|
|
214
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
215
|
+
* - `null`: drop the span entirely from every ship path.
|
|
216
|
+
*
|
|
217
|
+
* The hook runs BEFORE the default redactor (which is the always-on floor
|
|
218
|
+
* for documented BYOK secrets). The default redactor still runs on the
|
|
219
|
+
* post-transform span unless `disableDefaultRedaction` is set, so even if
|
|
220
|
+
* a custom transform overlooks a secret-shaped attribute, the floor catches
|
|
221
|
+
* it.
|
|
222
|
+
*
|
|
223
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
224
|
+
* If the hook itself throws, the span is dropped (fail-closed) so a buggy
|
|
225
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
226
|
+
*/
|
|
227
|
+
transformSpan?: TransformSpanHook;
|
|
228
|
+
/**
|
|
229
|
+
* Disable the built-in default span transformer (which scrubs documented
|
|
230
|
+
* secret-shaped properties — `apiKey`, `secretAccessKey`, `privateKey`,
|
|
231
|
+
* etc. — inside `ai.request.providerOptions` and
|
|
232
|
+
* `ai.response.providerMetadata`).
|
|
233
|
+
*
|
|
234
|
+
* Default: `false` (i.e. default redaction is on). Setting this to `true`
|
|
235
|
+
* disables the floor entirely; provide a custom `transformSpan` if you
|
|
236
|
+
* still want some redaction in that case.
|
|
237
|
+
*/
|
|
238
|
+
disableDefaultRedaction?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Per-attribute character cap applied to every span attribute string value
|
|
241
|
+
* right before the span enters a ship path, so a multi-MB prompt/tool
|
|
242
|
+
* payload can never make the batch `JSON.stringify` (which runs on the
|
|
243
|
+
* event loop) cost seconds. Truncated values end with
|
|
244
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
245
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
246
|
+
*/
|
|
247
|
+
maxTextFieldChars?: number;
|
|
140
248
|
};
|
|
141
249
|
declare class TraceShipper {
|
|
142
250
|
private baseUrl;
|
|
@@ -154,9 +262,51 @@ declare class TraceShipper {
|
|
|
154
262
|
private queue;
|
|
155
263
|
private timer;
|
|
156
264
|
private inFlight;
|
|
157
|
-
/** URL of the local debugger
|
|
265
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
158
266
|
private localDebuggerUrl;
|
|
267
|
+
private transformSpanHook;
|
|
268
|
+
private disableDefaultRedaction;
|
|
269
|
+
private maxTextFieldCharsOpt;
|
|
270
|
+
/**
|
|
271
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
272
|
+
* Checked before every batch POST issued during the final flush.
|
|
273
|
+
*/
|
|
274
|
+
private shutdownDeadlineAt;
|
|
275
|
+
/**
|
|
276
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
277
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
278
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
279
|
+
* retry schedule.
|
|
280
|
+
*/
|
|
281
|
+
private hasShutdown;
|
|
159
282
|
constructor(opts: TraceShipperOptions);
|
|
283
|
+
/**
|
|
284
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
285
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
286
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
287
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
288
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
289
|
+
* in the surviving prefix).
|
|
290
|
+
*
|
|
291
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
292
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
293
|
+
*/
|
|
294
|
+
private capSpanAttributes;
|
|
295
|
+
/**
|
|
296
|
+
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
297
|
+
* redactor (unless disabled). Returns either the (possibly new) span to
|
|
298
|
+
* ship, or `null` to drop the span entirely.
|
|
299
|
+
*
|
|
300
|
+
* Ordering: user hook runs first so callers can rewrite the span freely
|
|
301
|
+
* (rename attrs, add new ones, scrub things the default doesn't know
|
|
302
|
+
* about). The default redactor then runs on whatever the user produced,
|
|
303
|
+
* acting as the always-on floor for documented BYOK secrets. If the user
|
|
304
|
+
* sets `disableDefaultRedaction: true`, the floor is skipped.
|
|
305
|
+
*
|
|
306
|
+
* Fail-closed: if the user hook throws, the span is dropped — a buggy
|
|
307
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
308
|
+
*/
|
|
309
|
+
private redactSpan;
|
|
160
310
|
isDebugEnabled(): boolean;
|
|
161
311
|
private authHeaders;
|
|
162
312
|
startSpan(args: {
|
|
@@ -170,6 +320,7 @@ declare class TraceShipper {
|
|
|
170
320
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
171
321
|
startTimeUnixNano?: string;
|
|
172
322
|
}): InternalSpan;
|
|
323
|
+
private mirrorToLocalDebugger;
|
|
173
324
|
endSpan(span: InternalSpan, extra?: {
|
|
174
325
|
attributes?: InternalSpan["attributes"];
|
|
175
326
|
error?: unknown;
|
|
@@ -190,6 +341,8 @@ declare class TraceShipper {
|
|
|
190
341
|
}): void;
|
|
191
342
|
enqueue(span: OtlpSpan): void;
|
|
192
343
|
flush(): Promise<void>;
|
|
344
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
345
|
+
private requestOpts;
|
|
193
346
|
shutdown(): Promise<void>;
|
|
194
347
|
}
|
|
195
348
|
|