@raindrop-ai/langchain 0.0.3 → 0.0.5
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 +2 -1
- package/dist/index.d.mts +189 -2
- package/dist/index.d.ts +189 -2
- package/dist/index.js +695 -102
- package/dist/index.mjs +695 -102
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ import { ChatOpenAI } from "@langchain/openai";
|
|
|
16
16
|
import { HumanMessage } from "@langchain/core/messages";
|
|
17
17
|
|
|
18
18
|
const raindrop = createRaindropLangChain({
|
|
19
|
-
writeKey: "
|
|
19
|
+
writeKey: "your-write-key",
|
|
20
20
|
userId: "user-123",
|
|
21
21
|
});
|
|
22
22
|
|
|
@@ -50,6 +50,7 @@ await raindrop.flush();
|
|
|
50
50
|
| `traceChains` | `boolean` | `true` | Create spans for chain execution |
|
|
51
51
|
| `traceRetrievers` | `boolean` | `true` | Create spans for retriever calls |
|
|
52
52
|
| `filterLangGraphInternals` | `boolean` | `true` | Filter LangGraph-internal chain events and deduplicate LLM callbacks |
|
|
53
|
+
| `maxTextFieldChars` | `number` | `1000000` | Per-field cap for event input/output and serialized span payloads, enforced before/during serialization (truncated values end with `...[truncated by raindrop]`; a stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored) |
|
|
53
54
|
|
|
54
55
|
## LangGraph Support
|
|
55
56
|
|
package/dist/index.d.mts
CHANGED
|
@@ -43,7 +43,6 @@ type SpanIds = {
|
|
|
43
43
|
spanIdB64: string;
|
|
44
44
|
parentSpanIdB64?: string;
|
|
45
45
|
};
|
|
46
|
-
|
|
47
46
|
type Attachment = {
|
|
48
47
|
type: string;
|
|
49
48
|
role: string;
|
|
@@ -87,6 +86,26 @@ type EventShipperOptions = {
|
|
|
87
86
|
libraryName?: string;
|
|
88
87
|
libraryVersion?: string;
|
|
89
88
|
defaultEventName?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
91
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
92
|
+
*/
|
|
93
|
+
localDebuggerUrl?: string | null;
|
|
94
|
+
/**
|
|
95
|
+
* Optional project slug. When set, every outbound cloud request includes an
|
|
96
|
+
* `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
|
|
97
|
+
* values are ignored. Slug format is validated on construction but never
|
|
98
|
+
* throws — the backend returns 400 on invalid values.
|
|
99
|
+
*/
|
|
100
|
+
projectId?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Per-field character cap applied to event input/output BEFORE buffering
|
|
103
|
+
* or serialization, so oversized payloads cost the cap — not the payload —
|
|
104
|
+
* on the calling code path. Truncated fields end with
|
|
105
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
106
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
107
|
+
*/
|
|
108
|
+
maxTextFieldChars?: number;
|
|
90
109
|
};
|
|
91
110
|
declare class EventShipper {
|
|
92
111
|
private baseUrl;
|
|
@@ -97,14 +116,46 @@ declare class EventShipper {
|
|
|
97
116
|
private sdkName;
|
|
98
117
|
private prefix;
|
|
99
118
|
private defaultEventName;
|
|
119
|
+
private projectId;
|
|
100
120
|
private context;
|
|
101
121
|
private buffers;
|
|
102
122
|
private sticky;
|
|
103
123
|
private timers;
|
|
104
124
|
private inFlight;
|
|
125
|
+
private maxTextFieldCharsOpt;
|
|
126
|
+
/**
|
|
127
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
128
|
+
* Checked before every POST issued during the final flush.
|
|
129
|
+
*/
|
|
130
|
+
private shutdownDeadlineAt;
|
|
131
|
+
/**
|
|
132
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
133
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
134
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
135
|
+
* retry schedule.
|
|
136
|
+
*/
|
|
137
|
+
private hasShutdown;
|
|
138
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
139
|
+
private localDebuggerUrl;
|
|
105
140
|
constructor(opts: EventShipperOptions);
|
|
106
141
|
isDebugEnabled(): boolean;
|
|
107
142
|
private authHeaders;
|
|
143
|
+
private requestHeaders;
|
|
144
|
+
/**
|
|
145
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
146
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
147
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
148
|
+
* of issuing a request that could outlive process exit.
|
|
149
|
+
*
|
|
150
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
151
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
152
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
153
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
154
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
155
|
+
* run as a single short attempt rather than regaining the full retry
|
|
156
|
+
* schedule.
|
|
157
|
+
*/
|
|
158
|
+
private requestOpts;
|
|
108
159
|
patch(eventId: string, patch: Patch): Promise<void>;
|
|
109
160
|
finish(eventId: string, patch: {
|
|
110
161
|
output?: string;
|
|
@@ -116,8 +167,26 @@ declare class EventShipper {
|
|
|
116
167
|
shutdown(): Promise<void>;
|
|
117
168
|
trackSignal(signal: SignalInput): Promise<void>;
|
|
118
169
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
170
|
+
private warnShutdownDrop;
|
|
119
171
|
private flushOne;
|
|
120
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Hook fired per OTLP span right before the span is shipped (to the Raindrop
|
|
175
|
+
* API and to a local debugger). Lets callers inspect, rewrite, or drop the
|
|
176
|
+
* entire span — not just individual attributes — which is more flexible than
|
|
177
|
+
* an attribute-level hook (you can rename attributes, add new ones, drop the
|
|
178
|
+
* span outright, etc.).
|
|
179
|
+
*
|
|
180
|
+
* Return values:
|
|
181
|
+
* - `undefined` or the same span: ship the span unchanged.
|
|
182
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
183
|
+
* - `null`: drop the span entirely from every ship path.
|
|
184
|
+
*
|
|
185
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
186
|
+
* If the hook throws, the span is dropped (fail-closed) so a buggy hook can
|
|
187
|
+
* never accidentally ship raw, un-redacted spans.
|
|
188
|
+
*/
|
|
189
|
+
type TransformSpanHook = (span: OtlpSpan) => OtlpSpan | null | undefined;
|
|
121
190
|
|
|
122
191
|
type InternalSpan = {
|
|
123
192
|
ids: SpanIds;
|
|
@@ -138,6 +207,61 @@ type TraceShipperOptions = {
|
|
|
138
207
|
sdkName?: string;
|
|
139
208
|
serviceName?: string;
|
|
140
209
|
serviceVersion?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
212
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
213
|
+
*/
|
|
214
|
+
localDebuggerUrl?: string | null;
|
|
215
|
+
/**
|
|
216
|
+
* Optional project slug. When set, every OTLP trace export includes an
|
|
217
|
+
* `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
|
|
218
|
+
* values are ignored. Slug format is validated on construction but never
|
|
219
|
+
* throws — the backend returns 400 on invalid values.
|
|
220
|
+
*/
|
|
221
|
+
projectId?: string;
|
|
222
|
+
/**
|
|
223
|
+
* Per-span hook that fires for every OTLP span right before the span is
|
|
224
|
+
* shipped (both to the Raindrop API and to a local debugger). Lets callers
|
|
225
|
+
* inspect, rewrite, or drop entire spans — rename attributes, add new ones,
|
|
226
|
+
* scrub additional secret-shaped values inside `ai.prompt.messages` /
|
|
227
|
+
* `ai.toolCall.args`, etc.
|
|
228
|
+
*
|
|
229
|
+
* Return values:
|
|
230
|
+
* - `undefined` or the same span reference: ship the span unchanged.
|
|
231
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
232
|
+
* - `null`: drop the span entirely from every ship path.
|
|
233
|
+
*
|
|
234
|
+
* The hook runs BEFORE the default redactor (which is the always-on floor
|
|
235
|
+
* for documented BYOK secrets). The default redactor still runs on the
|
|
236
|
+
* post-transform span unless `disableDefaultRedaction` is set, so even if
|
|
237
|
+
* a custom transform overlooks a secret-shaped attribute, the floor catches
|
|
238
|
+
* it.
|
|
239
|
+
*
|
|
240
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
241
|
+
* If the hook itself throws, the span is dropped (fail-closed) so a buggy
|
|
242
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
243
|
+
*/
|
|
244
|
+
transformSpan?: TransformSpanHook;
|
|
245
|
+
/**
|
|
246
|
+
* Disable the built-in default span transformer (which scrubs documented
|
|
247
|
+
* secret-shaped properties — `apiKey`, `secretAccessKey`, `privateKey`,
|
|
248
|
+
* etc. — inside `ai.request.providerOptions` and
|
|
249
|
+
* `ai.response.providerMetadata`).
|
|
250
|
+
*
|
|
251
|
+
* Default: `false` (i.e. default redaction is on). Setting this to `true`
|
|
252
|
+
* disables the floor entirely; provide a custom `transformSpan` if you
|
|
253
|
+
* still want some redaction in that case.
|
|
254
|
+
*/
|
|
255
|
+
disableDefaultRedaction?: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Per-attribute character cap applied to every span attribute string value
|
|
258
|
+
* right before the span enters a ship path, so a multi-MB prompt/tool
|
|
259
|
+
* payload can never make the batch `JSON.stringify` (which runs on the
|
|
260
|
+
* event loop) cost seconds. Truncated values end with
|
|
261
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
262
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
263
|
+
*/
|
|
264
|
+
maxTextFieldChars?: number;
|
|
141
265
|
};
|
|
142
266
|
declare class TraceShipper {
|
|
143
267
|
private baseUrl;
|
|
@@ -152,14 +276,58 @@ declare class TraceShipper {
|
|
|
152
276
|
private flushIntervalMs;
|
|
153
277
|
private maxBatchSize;
|
|
154
278
|
private maxQueueSize;
|
|
279
|
+
private projectId;
|
|
155
280
|
private queue;
|
|
156
281
|
private timer;
|
|
157
282
|
private inFlight;
|
|
158
|
-
/** URL of the local debugger
|
|
283
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
159
284
|
private localDebuggerUrl;
|
|
285
|
+
private transformSpanHook;
|
|
286
|
+
private disableDefaultRedaction;
|
|
287
|
+
private maxTextFieldCharsOpt;
|
|
288
|
+
/**
|
|
289
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
290
|
+
* Checked before every batch POST issued during the final flush.
|
|
291
|
+
*/
|
|
292
|
+
private shutdownDeadlineAt;
|
|
293
|
+
/**
|
|
294
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
295
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
296
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
297
|
+
* retry schedule.
|
|
298
|
+
*/
|
|
299
|
+
private hasShutdown;
|
|
160
300
|
constructor(opts: TraceShipperOptions);
|
|
301
|
+
/**
|
|
302
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
303
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
304
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
305
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
306
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
307
|
+
* in the surviving prefix).
|
|
308
|
+
*
|
|
309
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
310
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
311
|
+
*/
|
|
312
|
+
private capSpanAttributes;
|
|
313
|
+
/**
|
|
314
|
+
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
315
|
+
* redactor (unless disabled). Returns either the (possibly new) span to
|
|
316
|
+
* ship, or `null` to drop the span entirely.
|
|
317
|
+
*
|
|
318
|
+
* Ordering: user hook runs first so callers can rewrite the span freely
|
|
319
|
+
* (rename attrs, add new ones, scrub things the default doesn't know
|
|
320
|
+
* about). The default redactor then runs on whatever the user produced,
|
|
321
|
+
* acting as the always-on floor for documented BYOK secrets. If the user
|
|
322
|
+
* sets `disableDefaultRedaction: true`, the floor is skipped.
|
|
323
|
+
*
|
|
324
|
+
* Fail-closed: if the user hook throws, the span is dropped — a buggy
|
|
325
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
326
|
+
*/
|
|
327
|
+
private redactSpan;
|
|
161
328
|
isDebugEnabled(): boolean;
|
|
162
329
|
private authHeaders;
|
|
330
|
+
private requestHeaders;
|
|
163
331
|
startSpan(args: {
|
|
164
332
|
name: string;
|
|
165
333
|
parent?: {
|
|
@@ -171,6 +339,7 @@ declare class TraceShipper {
|
|
|
171
339
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
172
340
|
startTimeUnixNano?: string;
|
|
173
341
|
}): InternalSpan;
|
|
342
|
+
private mirrorToLocalDebugger;
|
|
174
343
|
endSpan(span: InternalSpan, extra?: {
|
|
175
344
|
attributes?: InternalSpan["attributes"];
|
|
176
345
|
error?: unknown;
|
|
@@ -191,6 +360,8 @@ declare class TraceShipper {
|
|
|
191
360
|
}): void;
|
|
192
361
|
enqueue(span: OtlpSpan): void;
|
|
193
362
|
flush(): Promise<void>;
|
|
363
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
364
|
+
private requestOpts;
|
|
194
365
|
shutdown(): Promise<void>;
|
|
195
366
|
}
|
|
196
367
|
|
|
@@ -288,6 +459,12 @@ interface LangChainOptions {
|
|
|
288
459
|
debug?: boolean;
|
|
289
460
|
userId?: string;
|
|
290
461
|
convoId?: string;
|
|
462
|
+
/**
|
|
463
|
+
* Optional Raindrop project slug. When set, every outbound cloud request
|
|
464
|
+
* carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
|
|
465
|
+
* resolves to `default` server-side; byte-identical to prior behavior).
|
|
466
|
+
*/
|
|
467
|
+
projectId?: string;
|
|
291
468
|
traceChains?: boolean;
|
|
292
469
|
traceRetrievers?: boolean;
|
|
293
470
|
/**
|
|
@@ -295,6 +472,16 @@ interface LangChainOptions {
|
|
|
295
472
|
* Recommended when using LangGraph. Defaults to `true`.
|
|
296
473
|
*/
|
|
297
474
|
filterLangGraphInternals?: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Per-field character cap applied to event input/output text and
|
|
477
|
+
* serialized span payloads BEFORE (or during) serialization, so oversized
|
|
478
|
+
* payloads cost the cap — not the payload — on the calling thread.
|
|
479
|
+
* Truncated values end with `...[truncated by raindrop]` and never exceed
|
|
480
|
+
* the cap. Applies module-wide: the last factory call that sets this
|
|
481
|
+
* option wins; omitting it leaves the current cap unchanged. Defaults to
|
|
482
|
+
* 1,000,000.
|
|
483
|
+
*/
|
|
484
|
+
maxTextFieldChars?: number;
|
|
298
485
|
}
|
|
299
486
|
type RaindropLangChainClient = {
|
|
300
487
|
handler: RaindropCallbackHandler;
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,6 @@ type SpanIds = {
|
|
|
43
43
|
spanIdB64: string;
|
|
44
44
|
parentSpanIdB64?: string;
|
|
45
45
|
};
|
|
46
|
-
|
|
47
46
|
type Attachment = {
|
|
48
47
|
type: string;
|
|
49
48
|
role: string;
|
|
@@ -87,6 +86,26 @@ type EventShipperOptions = {
|
|
|
87
86
|
libraryName?: string;
|
|
88
87
|
libraryVersion?: string;
|
|
89
88
|
defaultEventName?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
91
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
92
|
+
*/
|
|
93
|
+
localDebuggerUrl?: string | null;
|
|
94
|
+
/**
|
|
95
|
+
* Optional project slug. When set, every outbound cloud request includes an
|
|
96
|
+
* `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
|
|
97
|
+
* values are ignored. Slug format is validated on construction but never
|
|
98
|
+
* throws — the backend returns 400 on invalid values.
|
|
99
|
+
*/
|
|
100
|
+
projectId?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Per-field character cap applied to event input/output BEFORE buffering
|
|
103
|
+
* or serialization, so oversized payloads cost the cap — not the payload —
|
|
104
|
+
* on the calling code path. Truncated fields end with
|
|
105
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
106
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
107
|
+
*/
|
|
108
|
+
maxTextFieldChars?: number;
|
|
90
109
|
};
|
|
91
110
|
declare class EventShipper {
|
|
92
111
|
private baseUrl;
|
|
@@ -97,14 +116,46 @@ declare class EventShipper {
|
|
|
97
116
|
private sdkName;
|
|
98
117
|
private prefix;
|
|
99
118
|
private defaultEventName;
|
|
119
|
+
private projectId;
|
|
100
120
|
private context;
|
|
101
121
|
private buffers;
|
|
102
122
|
private sticky;
|
|
103
123
|
private timers;
|
|
104
124
|
private inFlight;
|
|
125
|
+
private maxTextFieldCharsOpt;
|
|
126
|
+
/**
|
|
127
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
128
|
+
* Checked before every POST issued during the final flush.
|
|
129
|
+
*/
|
|
130
|
+
private shutdownDeadlineAt;
|
|
131
|
+
/**
|
|
132
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
133
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
134
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
135
|
+
* retry schedule.
|
|
136
|
+
*/
|
|
137
|
+
private hasShutdown;
|
|
138
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
139
|
+
private localDebuggerUrl;
|
|
105
140
|
constructor(opts: EventShipperOptions);
|
|
106
141
|
isDebugEnabled(): boolean;
|
|
107
142
|
private authHeaders;
|
|
143
|
+
private requestHeaders;
|
|
144
|
+
/**
|
|
145
|
+
* Build the retry/timeout options for one POST, honoring the shutdown
|
|
146
|
+
* deadline. Returns `null` when the shutdown drain window is exhausted —
|
|
147
|
+
* the caller must drop the payload (with a rate-limited warning) instead
|
|
148
|
+
* of issuing a request that could outlive process exit.
|
|
149
|
+
*
|
|
150
|
+
* Checked fresh on EVERY send, so a shutdown that begins while the flush
|
|
151
|
+
* path is mid-drain takes effect immediately: no further retries, and the
|
|
152
|
+
* per-attempt timeout is clamped to the remaining window. After
|
|
153
|
+
* `shutdown()` returns (deadline cleared, `hasShutdown` still set),
|
|
154
|
+
* sends — late callers, or flush work the deadline abandoned mid-drain —
|
|
155
|
+
* run as a single short attempt rather than regaining the full retry
|
|
156
|
+
* schedule.
|
|
157
|
+
*/
|
|
158
|
+
private requestOpts;
|
|
108
159
|
patch(eventId: string, patch: Patch): Promise<void>;
|
|
109
160
|
finish(eventId: string, patch: {
|
|
110
161
|
output?: string;
|
|
@@ -116,8 +167,26 @@ declare class EventShipper {
|
|
|
116
167
|
shutdown(): Promise<void>;
|
|
117
168
|
trackSignal(signal: SignalInput): Promise<void>;
|
|
118
169
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
170
|
+
private warnShutdownDrop;
|
|
119
171
|
private flushOne;
|
|
120
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Hook fired per OTLP span right before the span is shipped (to the Raindrop
|
|
175
|
+
* API and to a local debugger). Lets callers inspect, rewrite, or drop the
|
|
176
|
+
* entire span — not just individual attributes — which is more flexible than
|
|
177
|
+
* an attribute-level hook (you can rename attributes, add new ones, drop the
|
|
178
|
+
* span outright, etc.).
|
|
179
|
+
*
|
|
180
|
+
* Return values:
|
|
181
|
+
* - `undefined` or the same span: ship the span unchanged.
|
|
182
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
183
|
+
* - `null`: drop the span entirely from every ship path.
|
|
184
|
+
*
|
|
185
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
186
|
+
* If the hook throws, the span is dropped (fail-closed) so a buggy hook can
|
|
187
|
+
* never accidentally ship raw, un-redacted spans.
|
|
188
|
+
*/
|
|
189
|
+
type TransformSpanHook = (span: OtlpSpan) => OtlpSpan | null | undefined;
|
|
121
190
|
|
|
122
191
|
type InternalSpan = {
|
|
123
192
|
ids: SpanIds;
|
|
@@ -138,6 +207,61 @@ type TraceShipperOptions = {
|
|
|
138
207
|
sdkName?: string;
|
|
139
208
|
serviceName?: string;
|
|
140
209
|
serviceVersion?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Explicit Workshop / local debugger URL. Wins over env vars + auto-detect.
|
|
212
|
+
* Pass `null` to opt out of all mirroring (including auto-detect).
|
|
213
|
+
*/
|
|
214
|
+
localDebuggerUrl?: string | null;
|
|
215
|
+
/**
|
|
216
|
+
* Optional project slug. When set, every OTLP trace export includes an
|
|
217
|
+
* `X-Raindrop-Project-Id: <projectId>` header. Empty / whitespace-only
|
|
218
|
+
* values are ignored. Slug format is validated on construction but never
|
|
219
|
+
* throws — the backend returns 400 on invalid values.
|
|
220
|
+
*/
|
|
221
|
+
projectId?: string;
|
|
222
|
+
/**
|
|
223
|
+
* Per-span hook that fires for every OTLP span right before the span is
|
|
224
|
+
* shipped (both to the Raindrop API and to a local debugger). Lets callers
|
|
225
|
+
* inspect, rewrite, or drop entire spans — rename attributes, add new ones,
|
|
226
|
+
* scrub additional secret-shaped values inside `ai.prompt.messages` /
|
|
227
|
+
* `ai.toolCall.args`, etc.
|
|
228
|
+
*
|
|
229
|
+
* Return values:
|
|
230
|
+
* - `undefined` or the same span reference: ship the span unchanged.
|
|
231
|
+
* - a new `OtlpSpan`: ship the returned span in place of the original.
|
|
232
|
+
* - `null`: drop the span entirely from every ship path.
|
|
233
|
+
*
|
|
234
|
+
* The hook runs BEFORE the default redactor (which is the always-on floor
|
|
235
|
+
* for documented BYOK secrets). The default redactor still runs on the
|
|
236
|
+
* post-transform span unless `disableDefaultRedaction` is set, so even if
|
|
237
|
+
* a custom transform overlooks a secret-shaped attribute, the floor catches
|
|
238
|
+
* it.
|
|
239
|
+
*
|
|
240
|
+
* The hook runs on the hot path — keep it synchronous and side-effect-free.
|
|
241
|
+
* If the hook itself throws, the span is dropped (fail-closed) so a buggy
|
|
242
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
243
|
+
*/
|
|
244
|
+
transformSpan?: TransformSpanHook;
|
|
245
|
+
/**
|
|
246
|
+
* Disable the built-in default span transformer (which scrubs documented
|
|
247
|
+
* secret-shaped properties — `apiKey`, `secretAccessKey`, `privateKey`,
|
|
248
|
+
* etc. — inside `ai.request.providerOptions` and
|
|
249
|
+
* `ai.response.providerMetadata`).
|
|
250
|
+
*
|
|
251
|
+
* Default: `false` (i.e. default redaction is on). Setting this to `true`
|
|
252
|
+
* disables the floor entirely; provide a custom `transformSpan` if you
|
|
253
|
+
* still want some redaction in that case.
|
|
254
|
+
*/
|
|
255
|
+
disableDefaultRedaction?: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Per-attribute character cap applied to every span attribute string value
|
|
258
|
+
* right before the span enters a ship path, so a multi-MB prompt/tool
|
|
259
|
+
* payload can never make the batch `JSON.stringify` (which runs on the
|
|
260
|
+
* event loop) cost seconds. Truncated values end with
|
|
261
|
+
* `...[truncated by raindrop]` and never exceed the cap, marker included.
|
|
262
|
+
* Defaults to 1,000,000 (matching the Python SDK).
|
|
263
|
+
*/
|
|
264
|
+
maxTextFieldChars?: number;
|
|
141
265
|
};
|
|
142
266
|
declare class TraceShipper {
|
|
143
267
|
private baseUrl;
|
|
@@ -152,14 +276,58 @@ declare class TraceShipper {
|
|
|
152
276
|
private flushIntervalMs;
|
|
153
277
|
private maxBatchSize;
|
|
154
278
|
private maxQueueSize;
|
|
279
|
+
private projectId;
|
|
155
280
|
private queue;
|
|
156
281
|
private timer;
|
|
157
282
|
private inFlight;
|
|
158
|
-
/** URL of the local debugger
|
|
283
|
+
/** URL of the local debugger / Workshop daemon, when one is reachable. */
|
|
159
284
|
private localDebuggerUrl;
|
|
285
|
+
private transformSpanHook;
|
|
286
|
+
private disableDefaultRedaction;
|
|
287
|
+
private maxTextFieldCharsOpt;
|
|
288
|
+
/**
|
|
289
|
+
* Epoch ms deadline while `shutdown()` is draining; undefined otherwise.
|
|
290
|
+
* Checked before every batch POST issued during the final flush.
|
|
291
|
+
*/
|
|
292
|
+
private shutdownDeadlineAt;
|
|
293
|
+
/**
|
|
294
|
+
* Set once `shutdown()` begins and never cleared. Sends issued after the
|
|
295
|
+
* drain window (stragglers, or flush work the deadline abandoned
|
|
296
|
+
* mid-drain) run as a single short attempt instead of regaining the full
|
|
297
|
+
* retry schedule.
|
|
298
|
+
*/
|
|
299
|
+
private hasShutdown;
|
|
160
300
|
constructor(opts: TraceShipperOptions);
|
|
301
|
+
/**
|
|
302
|
+
* Cap every string attribute value on the span. O(#attributes) length
|
|
303
|
+
* checks; only oversized values pay a slice. Runs AFTER the redaction
|
|
304
|
+
* pipeline so the default secret-scrub still sees parseable JSON in
|
|
305
|
+
* `ai.request.providerOptions` / `ai.response.providerMetadata` (capping
|
|
306
|
+
* first could cut a JSON blob mid-way, fail the parse, and ship secrets
|
|
307
|
+
* in the surviving prefix).
|
|
308
|
+
*
|
|
309
|
+
* A stricter `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` env var is honored
|
|
310
|
+
* for span content, matching the Python SDK and the OTel SDK convention.
|
|
311
|
+
*/
|
|
312
|
+
private capSpanAttributes;
|
|
313
|
+
/**
|
|
314
|
+
* Apply the user `transformSpan` hook (if any) followed by the default
|
|
315
|
+
* redactor (unless disabled). Returns either the (possibly new) span to
|
|
316
|
+
* ship, or `null` to drop the span entirely.
|
|
317
|
+
*
|
|
318
|
+
* Ordering: user hook runs first so callers can rewrite the span freely
|
|
319
|
+
* (rename attrs, add new ones, scrub things the default doesn't know
|
|
320
|
+
* about). The default redactor then runs on whatever the user produced,
|
|
321
|
+
* acting as the always-on floor for documented BYOK secrets. If the user
|
|
322
|
+
* sets `disableDefaultRedaction: true`, the floor is skipped.
|
|
323
|
+
*
|
|
324
|
+
* Fail-closed: if the user hook throws, the span is dropped — a buggy
|
|
325
|
+
* hook can never accidentally ship raw, un-redacted spans.
|
|
326
|
+
*/
|
|
327
|
+
private redactSpan;
|
|
161
328
|
isDebugEnabled(): boolean;
|
|
162
329
|
private authHeaders;
|
|
330
|
+
private requestHeaders;
|
|
163
331
|
startSpan(args: {
|
|
164
332
|
name: string;
|
|
165
333
|
parent?: {
|
|
@@ -171,6 +339,7 @@ declare class TraceShipper {
|
|
|
171
339
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
172
340
|
startTimeUnixNano?: string;
|
|
173
341
|
}): InternalSpan;
|
|
342
|
+
private mirrorToLocalDebugger;
|
|
174
343
|
endSpan(span: InternalSpan, extra?: {
|
|
175
344
|
attributes?: InternalSpan["attributes"];
|
|
176
345
|
error?: unknown;
|
|
@@ -191,6 +360,8 @@ declare class TraceShipper {
|
|
|
191
360
|
}): void;
|
|
192
361
|
enqueue(span: OtlpSpan): void;
|
|
193
362
|
flush(): Promise<void>;
|
|
363
|
+
/** See EventShipper.requestOpts — same shutdown-budget semantics. */
|
|
364
|
+
private requestOpts;
|
|
194
365
|
shutdown(): Promise<void>;
|
|
195
366
|
}
|
|
196
367
|
|
|
@@ -288,6 +459,12 @@ interface LangChainOptions {
|
|
|
288
459
|
debug?: boolean;
|
|
289
460
|
userId?: string;
|
|
290
461
|
convoId?: string;
|
|
462
|
+
/**
|
|
463
|
+
* Optional Raindrop project slug. When set, every outbound cloud request
|
|
464
|
+
* carries an `X-Raindrop-Project-Id` header. Unset → no header (the project
|
|
465
|
+
* resolves to `default` server-side; byte-identical to prior behavior).
|
|
466
|
+
*/
|
|
467
|
+
projectId?: string;
|
|
291
468
|
traceChains?: boolean;
|
|
292
469
|
traceRetrievers?: boolean;
|
|
293
470
|
/**
|
|
@@ -295,6 +472,16 @@ interface LangChainOptions {
|
|
|
295
472
|
* Recommended when using LangGraph. Defaults to `true`.
|
|
296
473
|
*/
|
|
297
474
|
filterLangGraphInternals?: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Per-field character cap applied to event input/output text and
|
|
477
|
+
* serialized span payloads BEFORE (or during) serialization, so oversized
|
|
478
|
+
* payloads cost the cap — not the payload — on the calling thread.
|
|
479
|
+
* Truncated values end with `...[truncated by raindrop]` and never exceed
|
|
480
|
+
* the cap. Applies module-wide: the last factory call that sets this
|
|
481
|
+
* option wins; omitting it leaves the current cap unchanged. Defaults to
|
|
482
|
+
* 1,000,000.
|
|
483
|
+
*/
|
|
484
|
+
maxTextFieldChars?: number;
|
|
298
485
|
}
|
|
299
486
|
type RaindropLangChainClient = {
|
|
300
487
|
handler: RaindropCallbackHandler;
|