@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 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: "rk_...",
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 (from RAINDROP_LOCAL_DEBUGGER env var). */
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 (from RAINDROP_LOCAL_DEBUGGER env var). */
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;