raindrop-ai 0.4.0 → 0.5.0

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.
@@ -1,1525 +0,0 @@
1
- import * as _opentelemetry_instrumentation from '@opentelemetry/instrumentation';
2
- import { Instrumentation } from '@opentelemetry/instrumentation';
3
- import { Span, ContextManager as ContextManager$1, TextMapPropagator } from '@opentelemetry/api';
4
- import { z } from 'zod';
5
- import { SpanExporter, SpanProcessor } from '@opentelemetry/sdk-trace-base';
6
-
7
- /** The reverse reference a detached child carries on its own spans. */
8
- type DetachedChildLink = {
9
- /** The caller's event id. */
10
- parentEventId: string;
11
- /** The dispatch span id, hex-encoded as the backend stores span ids. */
12
- parentSpanId?: string;
13
- name?: string;
14
- };
15
-
16
- /**
17
- * Portable trace-context carrier for cross-process sub-agents.
18
- *
19
- * `toHeaders()` / `fromHeaders()` mirror LangSmith's
20
- * `RunTree.toHeaders()` / `tracing_context(parent=headers)` so migrating from
21
- * LangSmith is a rename rather than a redesign.
22
- *
23
- * Two carriers are understood:
24
- *
25
- * 1. Native — `x-raindrop-handoff`, plus W3C `traceparent` and a `baggage` of
26
- * `raindrop-*` keys. The standard pair is what other readers understand;
27
- * the Raindrop header is what survives an instrumented caller, and wins
28
- * where they disagree. See {@link HANDOFF_HEADER}.
29
- * 2. LangSmith — `langsmith-trace` (dotted order) plus LangSmith's `baggage`.
30
- * Accepted on READ so a service already propagating LangSmith headers links
31
- * correctly with no call-site change.
32
- *
33
- * ## Trust boundary
34
- *
35
- * A carrier names the event a child will be attributed to, so accepting one from
36
- * an untrusted caller lets that caller write into another tenant's trace. Only
37
- * accept carriers from services inside your own trust boundary — the same
38
- * constraint LangSmith documents for distributed tracing. Never take a carrier
39
- * off a public, unauthenticated request.
40
- *
41
- * Trace and span ids are hex here, as W3C `traceparent` and the Raindrop backend
42
- * both represent them. Use `base64ToHex` when converting from the base64 ids
43
- * used inside the trace shippers.
44
- */
45
- type TraceCarrier = {
46
- /** Hex trace id (32 chars for a W3C-conformant id). */
47
- traceId: string;
48
- /** Hex span id of the dispatching span (16 chars for a W3C-conformant id). */
49
- spanId: string;
50
- /** Event the child should join (continuation) or reference (detached). */
51
- eventId: string;
52
- /** Set only for a detached hand-off: the child's OWN event id. */
53
- childEventId?: string;
54
- /** Sub-agent name, carried so the child can label its own run identically. */
55
- name?: string;
56
- convoId?: string;
57
- userId?: string;
58
- };
59
- /**
60
- * A header container that answers by name rather than by property.
61
- *
62
- * A WHATWG `Headers` — what fetch, Next.js route handlers, Hono, Remix and
63
- * Cloudflare Workers all call `request.headers` — keeps its fields in an
64
- * internal slot, so `headers["baggage"]` is `undefined` and `Object.entries()`
65
- * on one yields nothing. Next.js's `headers()` returns a `ReadonlyHeaders`,
66
- * which is that object sealed behind a Proxy. `get()` is the only way in, and it
67
- * is also where the spec puts case-insensitivity and the joining of repeated
68
- * fields — so the container does that work rather than {@link readHeader}
69
- * reimplementing it.
70
- */
71
- type HeaderLookup = {
72
- get(name: string): string | null | undefined;
73
- };
74
- type CarrierHeaders = Readonly<Record<string, string | string[] | undefined>> | HeaderLookup;
75
- type LocalDebuggerLiveEventType = "text_delta" | "reasoning_delta" | "tool_start" | "tool_result" | "status";
76
- type LocalDebuggerLiveEventInput$1 = {
77
- traceId: string;
78
- spanId?: string;
79
- type: LocalDebuggerLiveEventType | (string & {});
80
- content?: string;
81
- timestamp?: number;
82
- metadata?: Record<string, unknown>;
83
- };
84
-
85
- /**
86
- * Run telemetry egress with OpenTelemetry tracing suppressed.
87
- *
88
- * Why this exists
89
- * ---------------
90
- * Raindrop integrations ship spans/events over HTTP with the global `fetch`
91
- * (see {@link ../http.ts `postJson`}). When the host app also runs an OTel
92
- * fetch/undici instrumentation — e.g. `@vercel/otel`'s `registerOTel`, which
93
- * every Eve agent installs — that instrumentation wraps *our own* telemetry
94
- * POSTs in a `fetch POST <endpoint>` span. Those spans are then handed to the
95
- * very exporter that issued the request, so they get shipped right back to
96
- * Raindrop and Workshop as standalone "runs" (and, because each export issues
97
- * another fetch, they feed back on themselves). The result is a run list
98
- * flooded with `fetch POST .../v1/traces`, `.../events/track_partial` and
99
- * `.../live` entries that drown out the real agent turns — especially with
100
- * sub-agents, where every sandbox runs its own instrumentation.
101
- *
102
- * The OTel-blessed fix is to mark the active context as "tracing suppressed"
103
- * around the request; instrumentations check `isTracingSuppressed` and return
104
- * a no-op span instead of recording one. We do this through a hook stashed on
105
- * `globalThis` by the Node entrypoint ({@link ../index.node.ts}) so that:
106
- * - `@opentelemetry/api` / `@opentelemetry/core` stay *optional* — core never
107
- * hard-depends on them, and the hook is simply absent when they (and thus
108
- * any instrumentation to suppress) are not installed; and
109
- * - the browser bundle never pulls in `node:module`, mirroring how core
110
- * injects `AsyncLocalStorage` via `RAINDROP_ASYNC_LOCAL_STORAGE`.
111
- *
112
- * When no hook is present the callback runs unchanged, so suppression is a
113
- * best-effort no-op rather than a hard requirement.
114
- */
115
- /** Hook signature: run `fn` with OTel tracing suppressed, returning its value. */
116
- type SuppressTracingHook = <T>(fn: () => T) => T;
117
- declare global {
118
- var RAINDROP_SUPPRESS_TRACING: SuppressTracingHook | undefined;
119
- }
120
-
121
- type ParentSpanContext = {
122
- traceIdB64: string;
123
- spanIdB64: string;
124
- eventId: string;
125
- };
126
- interface ContextSpan {
127
- readonly traceIdB64: string;
128
- readonly spanIdB64: string;
129
- readonly eventId: string;
130
- log?(data: Record<string, unknown>): void;
131
- }
132
- interface AsyncLocalStorageLike<T> {
133
- getStore(): T | undefined;
134
- run<R>(store: T, callback: () => R): R;
135
- enterWith?(store: T): void;
136
- }
137
- declare abstract class ContextManager {
138
- abstract getParentSpanIds(): ParentSpanContext | undefined;
139
- abstract runInContext<R>(span: ContextSpan, callback: () => R): R;
140
- abstract getCurrentSpan(): ContextSpan | undefined;
141
- abstract isReady(): boolean;
142
- }
143
- declare global {
144
- var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
145
- var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
146
- }
147
-
148
- /**
149
- * Version-agnostic SpanProcessor interface.
150
- *
151
- * This interface avoids direct dependency on OTEL's Span and ReadableSpan types
152
- * which can cause compatibility issues across minor OTEL versions. Using `any`
153
- * allows the processor to work with any version of OTEL without type conflicts.
154
- */
155
- interface RaindropSpanProcessor {
156
- forceFlush(): Promise<void>;
157
- onStart(span: any, parentContext: any): void;
158
- onEnd(span: any): void;
159
- shutdown(): Promise<void>;
160
- }
161
- type BaseAttachment = {
162
- attachment_id?: string;
163
- name?: string;
164
- value: string;
165
- role: "input" | "output";
166
- };
167
- type CodeAttachment = BaseAttachment & {
168
- type: "code";
169
- language?: string;
170
- };
171
- type OtherAttachment = BaseAttachment & {
172
- type: "text" | "image" | "iframe";
173
- };
174
- type Attachment = CodeAttachment | OtherAttachment;
175
- type RaindropFeatureFlagValue = string | number | boolean;
176
- type RaindropFeatureFlags = string[] | Record<string, RaindropFeatureFlagValue>;
177
- type RaindropPropertyLeaf = string | boolean | number;
178
- type RaindropPropertyValue = RaindropPropertyLeaf | RaindropPropertyValue[] | {
179
- [key: string]: RaindropPropertyValue;
180
- };
181
- type RaindropProperties = Record<string, RaindropPropertyValue>;
182
- /**
183
- * Interface for tracking events.
184
- *
185
- * @param eventId - An optional event ID for the event.
186
- * @param event - The name of the event.
187
- * @param properties - An optional record of properties for the event.
188
- * @param timestamp - An optional timestamp for the event.
189
- * @param userId - The ID of the user. This is a required field.
190
- * @param anonymousId - An optional anonymous ID for the user.
191
- */
192
- interface TrackEvent {
193
- eventId?: string;
194
- event: string;
195
- properties?: RaindropProperties;
196
- featureFlags?: RaindropFeatureFlags;
197
- timestamp?: string;
198
- userId: string;
199
- }
200
- type BasicSignal = {
201
- eventId: string;
202
- name: "thumbs_up" | "thumbs_down" | string;
203
- sentiment?: "POSITIVE" | "NEGATIVE";
204
- timestamp?: string;
205
- properties?: {
206
- [key: string]: any;
207
- };
208
- attachmentId?: string;
209
- };
210
- type DefaultSignal = BasicSignal & {
211
- type?: "default" | "standard";
212
- };
213
- type FeedbackSignal = BasicSignal & {
214
- type: "feedback";
215
- comment?: string;
216
- };
217
- type EditSignal = BasicSignal & {
218
- type: "edit";
219
- after?: string;
220
- };
221
- type AgentSignal = BasicSignal & {
222
- type: "agent" | "agent_internal";
223
- };
224
- type SignalEvent = DefaultSignal | FeedbackSignal | EditSignal | AgentSignal;
225
- type SelfDiagnoseOptions = {
226
- /** The interaction/event ID this diagnostic belongs to. */
227
- eventId: string;
228
- /** A human-readable description of the issue. */
229
- description: string;
230
- /** Optional category to group the diagnostic under (e.g. "missing_context", "capability_gap"). Defaults to "general". */
231
- category?: string;
232
- /** Optional source identifier (e.g. your agent or service name). */
233
- source?: string;
234
- /** Signal sentiment. Defaults to "NEGATIVE". */
235
- sentiment?: "POSITIVE" | "NEGATIVE";
236
- /** Additional custom properties to attach to the signal. */
237
- properties?: Record<string, unknown>;
238
- };
239
- type SelfDiagnosticsSignalDefinition = {
240
- description: string;
241
- sentiment?: "POSITIVE" | "NEGATIVE";
242
- };
243
- type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
244
- type SelfDiagnosticsToolInputSchema = {
245
- type: "object";
246
- additionalProperties: false;
247
- properties: {
248
- category: {
249
- type: "string";
250
- enum: string[];
251
- description: string;
252
- };
253
- detail: {
254
- type: "string";
255
- description: string;
256
- };
257
- };
258
- required: string[];
259
- };
260
- type SelfDiagnosticsExecuteContext = {
261
- eventId?: string;
262
- interaction?: {
263
- getEventId(): string | undefined;
264
- };
265
- metadata?: Record<string, unknown>;
266
- properties?: Record<string, unknown>;
267
- source?: string;
268
- };
269
- type SelfDiagnosticsExecuteResult = {
270
- acknowledged: boolean;
271
- category: string;
272
- eventId?: string;
273
- reason?: "missing_event_id";
274
- };
275
- type SelfDiagnosticsToolOptions = {
276
- eventId?: string;
277
- getEventId?: () => string | undefined;
278
- interaction?: {
279
- getEventId(): string | undefined;
280
- };
281
- toolName?: string;
282
- guidance?: string;
283
- signals?: SelfDiagnosticsSignalDefinitions;
284
- source?: string;
285
- onMissingEventId?: "warn" | "ignore" | "throw";
286
- };
287
- type SelfDiagnosticsTool = {
288
- name: string;
289
- description: string;
290
- inputSchema: SelfDiagnosticsToolInputSchema;
291
- signalKeys: string[];
292
- execute(input: unknown, context?: SelfDiagnosticsExecuteContext): Promise<SelfDiagnosticsExecuteResult>;
293
- forVercelAI(): {
294
- description: string;
295
- parameters: SelfDiagnosticsToolInputSchema;
296
- inputSchema: SelfDiagnosticsToolInputSchema;
297
- execute: (input: unknown, context?: SelfDiagnosticsExecuteContext) => Promise<SelfDiagnosticsExecuteResult>;
298
- };
299
- forOpenAI(): {
300
- type: "function";
301
- function: {
302
- name: string;
303
- description: string;
304
- parameters: SelfDiagnosticsToolInputSchema;
305
- };
306
- };
307
- forAnthropic(): {
308
- name: string;
309
- description: string;
310
- input_schema: SelfDiagnosticsToolInputSchema;
311
- };
312
- };
313
- /**
314
- * Interface for identifying events.
315
- *
316
- * @param userId - The ID of the user. This is a required field.
317
- * @param traits - An optional object of traits for the user.
318
- * @param anonymousId - An optional anonymous ID for the user.
319
- * TODO: ensure at least one out of userId or anonymousId is present
320
- */
321
- interface IdentifyEvent {
322
- userId: string;
323
- traits?: object;
324
- }
325
- /**
326
- * Type definition for AI tracking events.
327
- * In addition to the properties of a TrackEvent, an AiTrackEvent may have a 'model' property.
328
- * It must have at least one of 'input' or 'output' property.
329
- *
330
- * @property model - An optional model property for the even
331
- * @property input - An optional input property for the event, required if output is not provided.
332
- * @property output - An optional output property for the event, required if input is not provided.
333
- */
334
- declare const AiTrackUsageSchema: z.ZodObject<{
335
- provider: z.ZodString;
336
- inputTokens: z.ZodNumber;
337
- outputTokens: z.ZodNumber;
338
- cacheReadTokens: z.ZodOptional<z.ZodNumber>;
339
- cacheWriteTokens: z.ZodOptional<z.ZodNumber>;
340
- reasoningTokens: z.ZodOptional<z.ZodNumber>;
341
- providerReportedCost: z.ZodOptional<z.ZodNumber>;
342
- }, "strip", z.ZodTypeAny, {
343
- provider: string;
344
- inputTokens: number;
345
- outputTokens: number;
346
- cacheReadTokens?: number | undefined;
347
- cacheWriteTokens?: number | undefined;
348
- reasoningTokens?: number | undefined;
349
- providerReportedCost?: number | undefined;
350
- }, {
351
- provider: string;
352
- inputTokens: number;
353
- outputTokens: number;
354
- cacheReadTokens?: number | undefined;
355
- cacheWriteTokens?: number | undefined;
356
- reasoningTokens?: number | undefined;
357
- providerReportedCost?: number | undefined;
358
- }>;
359
- type AiTrackUsage = z.infer<typeof AiTrackUsageSchema>;
360
- type AiTrackEvent = Omit<TrackEvent, "type"> & {
361
- model?: string;
362
- convoId?: string;
363
- attachments?: Attachment[];
364
- featureFlags?: RaindropFeatureFlags;
365
- /**
366
- * Raw values copied from the provider's usage object. Raindrop derives
367
- * provider-specific billing pools on the server.
368
- */
369
- usage?: AiTrackUsage;
370
- } & ({
371
- input: string;
372
- output?: string;
373
- } | {
374
- input?: string;
375
- output: string;
376
- });
377
- /**
378
- * Type definition for partial AI tracking events used with trackAiPartial.
379
- * Requires an eventId to correlate partial updates. All other fields are optional.
380
- */
381
- type PartialAiTrackEvent = Partial<AiTrackEvent> & {
382
- eventId: string;
383
- isPending?: boolean;
384
- };
385
- declare const AttachmentTypeSchema: z.ZodEnum<["code", "text", "image", "iframe"]>;
386
- type AttachmentType = z.infer<typeof AttachmentTypeSchema>;
387
- /**
388
- * Configuration for initializing a trace interaction.
389
- *
390
- * This interface defines the context required to create and track an AI
391
- * interaction through its lifecycle. It includes identifiers for the user
392
- * and conversation, as well as input/output content and attachments.
393
- *
394
- * @property userId - Optional unique identifier for the user
395
- * @property convoId - Optional unique identifier for the conversation
396
- * @property eventId - Optional unique identifier for this specific interaction event
397
- * @property input - Optional input text from the user
398
- * @property attachments - Optional array of attachments associated with this interaction
399
- * @property properties - Optional key-value pairs for additional custom metadata
400
- */
401
- interface TraceContext {
402
- userId?: string;
403
- convoId?: string;
404
- eventId?: string;
405
- input?: string;
406
- event?: string;
407
- attachments?: Attachment[];
408
- properties?: Record<string, string>;
409
- }
410
- type BeginInteractionOptions = PartialAiTrackEvent & {
411
- eventId: string;
412
- };
413
- type FinishInteractionOptions = Omit<PartialAiTrackEvent, "eventId"> & {
414
- output: string;
415
- eventId?: string;
416
- };
417
- /**
418
- * Configuration for a traced workflow.
419
- *
420
- * Workflows represent higher-level operations that might contain multiple
421
- * tasks. They help organize traces into logical units of work.
422
- *
423
- * @property name - Name of the workflow for identification in traces
424
- * @property inputParameters - Optional array of input parameters for the workflow
425
- * @property properties - Optional key-value pairs for additional metadata
426
- */
427
- interface WorkflowParams {
428
- name: string;
429
- inputParameters?: unknown[];
430
- properties?: Record<string, string>;
431
- }
432
- /**
433
- * Configuration for a traced task.
434
- *
435
- * Tasks represent individual operations within a workflow, such as an LLM call,
436
- * a tool invocation, a retrieval operation, or internal processing.
437
- *
438
- * @property name - Name of the task for identification in traces
439
- * @property kind - Category of the task (llm, tool, retrival, or internal)
440
- * @property properties - Optional key-value pairs for additional metadata
441
- * @property inputParameters - Optional array of input parameters for the task
442
- * @property traceContent - Optional flag to control whether content is traced
443
- * @property suppressTracing - Optional flag to suppress tracing for this task
444
- */
445
- interface SpanParams {
446
- name: string;
447
- properties?: Record<string, string>;
448
- inputParameters?: unknown[];
449
- traceContent?: boolean;
450
- suppressTracing?: boolean;
451
- }
452
- /**
453
- * Configuration for a traced tool.
454
- *
455
- * Tools represent external utilities or services that are invoked during an AI interaction,
456
- * such as search engines, calculators, or other specialized functions.
457
- *
458
- * @property name - Name of the tool for identification in traces
459
- * @property version - Optional version number of the tool
460
- * @property properties - Optional key-value pairs for additional metadata
461
- * @property inputParameters - Optional record of input parameters for the tool
462
- * @property traceContent - Optional flag to control whether content is traced
463
- * @property suppressTracing - Optional flag to suppress tracing for this tool invocation
464
- */
465
- interface ToolParams {
466
- name: string;
467
- version?: number;
468
- properties?: Record<string, string>;
469
- inputParameters?: Record<string, any>;
470
- traceContent?: boolean;
471
- suppressTracing?: boolean;
472
- }
473
- /**
474
- * Parameters for directly logging a tool span without wrapping a function.
475
- *
476
- * Use this when you want to record a tool invocation that has already completed,
477
- * rather than wrapping the tool call with withTool().
478
- *
479
- * @property name - Name of the tool for identification in traces
480
- * @property input - The input provided to the tool (will be JSON stringified if object)
481
- * @property output - The output returned by the tool (will be JSON stringified if object)
482
- * @property durationMs - Duration of the tool execution in milliseconds
483
- * @property startTime - Optional start time of the tool execution
484
- * @property error - Optional error if the tool failed
485
- * @property properties - Optional key-value pairs for additional metadata
486
- * @property traceId - Optional W3C trace ID override for bypassOtelForTools mode
487
- * @property parentSpanId - Optional W3C parent span ID override for bypassOtelForTools mode
488
- */
489
- interface TrackToolParams {
490
- name: string;
491
- input?: unknown;
492
- output?: unknown;
493
- durationMs?: number;
494
- startTime?: Date | number;
495
- error?: Error | string;
496
- properties?: Record<string, string>;
497
- traceId?: string;
498
- parentSpanId?: string;
499
- }
500
- type LocalDebuggerLiveEventInput = Omit<LocalDebuggerLiveEventInput$1, "traceId"> & {
501
- traceId?: string;
502
- };
503
- /**
504
- * Arguments for {@link Interaction.subagent}.
505
- *
506
- * Deliberately absent: anything describing how the child is doing. The caller
507
- * dispatched a job and moved on, so a status it wrote would be a guess that
508
- * goes stale — readers derive status from the child's own event.
509
- */
510
- interface SubagentDispatchOptions {
511
- /** Sub-agent name. The child labels its own run with the same value. */
512
- name: string;
513
- /** Launch arguments, recorded as the dispatch span's input. */
514
- input?: unknown;
515
- /**
516
- * Reuse an id the caller already has (a queue job id, say) instead of
517
- * minting one. Either way the id exists BEFORE dispatch, which is what makes
518
- * the link resolvable while the child is still queued.
519
- */
520
- childEventId?: string;
521
- /** Name of the dispatch span. Defaults to `launch_subagent`. */
522
- toolName?: string;
523
- /** Extra properties recorded on the dispatch span. */
524
- properties?: RaindropProperties;
525
- }
526
- /** The record of one detached dispatch, returned by {@link Interaction.subagent}. */
527
- interface SubagentDispatch {
528
- /** The child's own event id — the job handle to pass to the worker. */
529
- childEventId: string;
530
- name: string;
531
- /** The launching interaction's event id. */
532
- parentEventId: string;
533
- /** Hex id of the dispatch span, or `undefined` when none was recorded. */
534
- dispatchSpanId?: string;
535
- /**
536
- * The carrier behind the headers, for transports that are not HTTP.
537
- *
538
- * `null` when no dispatch span could be recorded (tracing disabled). There is
539
- * then no span for the child to reference, and `headers` is empty rather than
540
- * naming one that does not exist — pass `childEventId` to the worker yourself
541
- * if it must still report under that id.
542
- */
543
- carrier: TraceCarrier | null;
544
- /**
545
- * Native carrier headers: W3C `traceparent` + `raindrop-*` `baggage`, plus
546
- * `x-raindrop-handoff` carrying the same fields under a name no propagator
547
- * rewrites. Send all of them — instrumentation owns `traceparent` and the
548
- * baggage propagator REPLACES `baggage`, so the standard pair alone can arrive
549
- * emptied of every hand-off identity.
550
- *
551
- * TRUST BOUNDARY: send these only to services inside your own trust
552
- * boundary — a carrier names the event the child will be attributed to.
553
- */
554
- headers: Record<string, string>;
555
- /** The same carrier in LangSmith's header shape, for services that parse it. */
556
- langsmithHeaders: Record<string, string>;
557
- }
558
- /**
559
- * Fallbacks for a sub-agent run whose request carried no carrier, i.e. one
560
- * invoked directly rather than dispatched.
561
- *
562
- * These do NOT override a carrier. Every identity field here names something
563
- * the launcher already recorded, so a local value winning would strand the
564
- * child outside the link it exists to complete.
565
- */
566
- interface SubagentResumeOptions {
567
- /** Used when the carrier supplied no name. */
568
- name?: string;
569
- /** Used when the carrier supplied no child event id. */
570
- eventId?: string;
571
- userId?: string;
572
- convoId?: string;
573
- /** Event name for the child's own event. Defaults to `subagent.<name>`. */
574
- event?: string;
575
- input?: string;
576
- model?: string;
577
- properties?: RaindropProperties;
578
- /** Pre-parsed carrier, for transports that are not HTTP. */
579
- parent?: TraceCarrier | null;
580
- }
581
- /** How a detached sub-agent's run completes. */
582
- type SubagentFinishOptions = Omit<FinishInteractionOptions, "eventId">;
583
- /**
584
- * A detached sub-agent's own run, as seen from inside the sub-agent.
585
- *
586
- * Wraps the child's own Raindrop event and keeps the reverse reference bound to
587
- * the execution context, so every span the child emits while the run is open
588
- * carries it.
589
- */
590
- interface SubagentRun {
591
- /** The child's own Raindrop event. */
592
- readonly interaction: Interaction;
593
- /** The child's own event id, adopted from the carrier when it supplied one. */
594
- readonly eventId: string;
595
- readonly name: string;
596
- /** The conversation this run reports into — the launcher's when linked. */
597
- readonly convoId?: string;
598
- /**
599
- * The launching context, or `null` when the request carried no carrier.
600
- *
601
- * `null` is a legitimate state — the sub-agent was invoked directly rather
602
- * than dispatched — and the run still reports as its own event, just without
603
- * a link back.
604
- */
605
- readonly parent: DetachedChildLink | null;
606
- readonly linked: boolean;
607
- /** Complete the child's event with its result. */
608
- finish(result: SubagentFinishOptions): Promise<void>;
609
- /**
610
- * Report that the run aborted: error the child's own span, and say why in
611
- * the output.
612
- *
613
- * Both halves matter. The ERROR status is what makes the run read as
614
- * *failed* — status is derived from the child's telemetry, and a run with
615
- * output but no errored span is indistinguishable from one that succeeded.
616
- * The output is what makes the run exist at all: an event needs non-empty
617
- * output, so a child that closes empty leaves its launcher on `queued`
618
- * forever.
619
- */
620
- fail(reason: unknown): Promise<void>;
621
- /**
622
- * Mark the run cancelled — the one state its telemetry cannot express.
623
- *
624
- * A cancelled run is span-for-span identical to a finished one (spans close,
625
- * nothing errors, there is simply no answer), so it needs an explicit
626
- * marker. Written by the child on itself, never by the caller. Deliberately
627
- * does NOT error any span: error spans are what separate failed from
628
- * cancelled.
629
- */
630
- cancel(reason?: unknown): Promise<void>;
631
- }
632
- /**
633
- * A wrapper around an OpenTelemetry span for tool invocations.
634
- *
635
- * Provides a clean API for setting tool input, output, and error status
636
- * without needing to know the internal traceloop attribute names.
637
- *
638
- * @example
639
- * ```typescript
640
- * const toolSpan = interaction.startToolSpan({ name: "web_search" });
641
- * try {
642
- * const result = await performSearch(query);
643
- * toolSpan.setOutput(result);
644
- * } catch (error) {
645
- * toolSpan.setError(error);
646
- * } finally {
647
- * toolSpan.end();
648
- * }
649
- * ```
650
- */
651
- interface ToolSpan {
652
- /**
653
- * Sets the input for this tool span.
654
- * @param input The input value (will be JSON stringified if object)
655
- */
656
- setInput(input: unknown): void;
657
- /**
658
- * Sets the output for this tool span.
659
- * @param output The output value (will be JSON stringified if object)
660
- */
661
- setOutput(output: unknown): void;
662
- /**
663
- * Marks this tool span as failed with an error.
664
- * @param error The error that occurred
665
- */
666
- setError(error: Error | string): void;
667
- /**
668
- * Ends this tool span. Must be called when the tool execution is complete.
669
- */
670
- end(): void;
671
- }
672
- /**
673
- * Represents an active tracing interaction for tracking and analyzing AI interactions.
674
- *
675
- * An Interaction is the core entity for tracing and instrumenting AI operations,
676
- * allowing you to organize your code into workflows and tasks while capturing
677
- * important metadata and contextual information. Use the methods on this interface
678
- * to record your AI interaction's lifecycle from input to output, and to add
679
- * structured context about the operation.
680
- *
681
- * Interactions are typically created using the `tracing.begin()` method and ended
682
- * with the `end()` method. Between these calls, you can add properties, attachments,
683
- * and nested traced operations.
684
- *
685
- * @example
686
- * // Basic usage pattern
687
- * const interaction = tracing.begin({
688
- * userId: "user-123",
689
- * convoId: "conversation-456"
690
- * });
691
- *
692
- * // Set the user's input
693
- * interaction.setInput("Tell me a joke about AI");
694
- *
695
- * // Add context properties
696
- * interaction.setProperty("intent", "entertainment");
697
- *
698
- * // Run a traced workflow
699
- * const result = await interaction.withWorkflow("joke_generation", async () => {
700
- * // Run a traced task for the LLM call
701
- * return await interaction.withTask({
702
- * name: "llm_completion",
703
- * kind: "llm"
704
- * }, async () => {
705
- * const completion = await openai.chat.completions.create({
706
- * model: "gpt-4",
707
- * messages: [{ role: "user", content: "Tell me a joke about AI" }]
708
- * });
709
- * return completion.choices[0].message.content;
710
- * });
711
- * });
712
- *
713
- * // End the interaction with the result
714
- * interaction.end(result);
715
- */
716
- type Interaction = {
717
- /**
718
- * Creates a traced task that executes the provided function.
719
- *
720
- * @param params TaskParams object with task configuration
721
- * @returns A span that can be used to record a task
722
- */
723
- withSpan<T>(params: SpanParams, fn: (...args: any[]) => Promise<T> | T, thisArg?: any, ...args: any[]): Promise<T>;
724
- /**
725
- * Creates a traced tool that executes the provided function.
726
- *
727
- * Tools represent external utilities or services that are invoked during an AI interaction.
728
- * This method wraps a function call with tracing to capture the tool's inputs and outputs.
729
- *
730
- * @param params ToolParams object with tool configuration
731
- * @param fn Function to execute within the tool trace
732
- * @param thisArg Optional 'this' context for the function
733
- * @param args Optional arguments to pass to the function
734
- * @returns A promise that resolves with the tool execution result
735
- *
736
- * @example
737
- * // Basic tool usage
738
- * const result = await interaction.withTool(
739
- * { name: "search_tool" },
740
- * async () => {
741
- * // Call to external API or service
742
- * return "Search results";
743
- * }
744
- * );
745
- *
746
- * @example
747
- * // Basic tool usage
748
- * const result = await interaction.withTool(
749
- * {
750
- * name: "calculator",
751
- * properties: { operation: "multiply" },
752
- * inputParameters: { a: 5, b: 10 }
753
- * },
754
- * async () => {
755
- * // Tool implementation
756
- * return "Result: 50";
757
- * }
758
- * );
759
- */
760
- withTool<T>(params: ToolParams, fn: (...args: any[]) => Promise<T> | T, thisArg?: any, ...args: any[]): Promise<T>;
761
- /**
762
- * Creates a task span that can be used to manually record a task.
763
- *
764
- * @param params TaskParams object with task configuration
765
- * @returns A span that can be used to record a task
766
- */
767
- startSpan(params: SpanParams): Span;
768
- /**
769
- * Creates a tool span that can be used to manually record a tool invocation.
770
- *
771
- * Similar to startSpan but sets the span kind to "tool" instead of "task".
772
- * Use this when you want manual control over the span lifecycle for tool calls.
773
- * Returns a ToolSpan wrapper with convenient methods for setting input, output, and errors.
774
- *
775
- * @param params ToolParams object with tool configuration
776
- * @returns A ToolSpan wrapper for recording the tool execution
777
- *
778
- * @example
779
- * ```typescript
780
- * const interaction = raindrop.begin({ userId: "user-123", event: "agent_run" });
781
- *
782
- * // Start a tool span with manual control
783
- * const toolSpan = interaction.startToolSpan({ name: "web_search" });
784
- * try {
785
- * const result = await performSearch(query);
786
- * toolSpan.setOutput(result);
787
- * } catch (error) {
788
- * toolSpan.setError(error);
789
- * } finally {
790
- * toolSpan.end();
791
- * }
792
- * ```
793
- */
794
- startToolSpan(params: ToolParams): ToolSpan;
795
- /**
796
- * Sets multiple properties on the interaction context.
797
- *
798
- * @param properties Object containing properties to set
799
- */
800
- setProperties(properties: RaindropProperties): void;
801
- /**
802
- * Sets a single property on the interaction context.
803
- *
804
- * @param key The property key
805
- * @param value The property value
806
- */
807
- setProperty(key: string, value: RaindropPropertyValue): void;
808
- /**
809
- * Adds an attachment to the interaction.
810
- *
811
- * @param attachment The attachment to add
812
- *
813
- * @example
814
- * // Adding various attachment types to an interaction
815
- *
816
- * // 1. Text attachment for context
817
- * interaction.addAttachment([{
818
- * type: "text",
819
- * name: "Additional Info",
820
- * value: "A very long document",
821
- * role: "input",
822
- * }]);
823
- *
824
- * // 2. Image attachment (output)
825
- * interaction.addAttachment([{
826
- * type: "image",
827
- * value: "https://example.com/image.png",
828
- * role: "output"
829
- * }]);
830
- *
831
- * // 3. Iframe for embedded content
832
- * interaction.addAttachment([{
833
- * type: "iframe",
834
- * name: "Generated UI",
835
- * value: "https://newui.generated.com",
836
- * role: "output",
837
- * }]);
838
- *
839
- * // 4. Code snippet
840
- * interaction.addAttachment([{
841
- * type: "code",
842
- * name: "Generated SQL Query",
843
- * value: "SELECT * FROM users WHERE os_build = '17.1'",
844
- * role: "output",
845
- * language: "sql"
846
- * }]);
847
- *
848
- * // All attachments are included when the interaction ends
849
- * interaction.end("The weather is sunny and warm.");
850
- */
851
- addAttachments(attachments: Attachment[]): void;
852
- /**
853
- * Sets a single feature flag on the interaction.
854
- * @param name The flag name
855
- * @param value The flag value (defaults to "true")
856
- */
857
- setFeatureFlag(name: string, value?: RaindropFeatureFlagValue): void;
858
- /**
859
- * Sets multiple feature flags on the interaction.
860
- * Accepts an array of flag names (all set to "true") or an object with explicit values.
861
- * Merges with any previously set flags.
862
- * @param flags The feature flags to set
863
- */
864
- setFeatureFlags(flags: RaindropFeatureFlags): void;
865
- /**
866
- * Sets the input for the interaction.
867
- *
868
- * @param input The input string
869
- */
870
- setInput(input: string): void;
871
- /**
872
- * Ends the interaction and sends analytics data.
873
- *
874
- * This method completes the interaction lifecycle by:
875
- * 1. Setting the trace_id as a property (if available)
876
- * 2. Sending analytics data including the event ID, conversation ID,
877
- * user ID, input, output, attachments, and any custom properties
878
- *
879
- * @param output The final output string for this interaction
880
- *
881
- * @example
882
- * // Start and end an interaction
883
- * const interaction = tracing.begin({
884
- * userId: "user-123",
885
- * convoId: "convo-456"
886
- * });
887
- *
888
- * interaction.setInput("What can you help me with today?");
889
- * // ... process the request ...
890
- *
891
- * // End the interaction with the response
892
- * interaction.end("I can help you with various tasks. Here are some examples...");
893
- */
894
- finish(resultEvent: FinishInteractionOptions): Promise<void>;
895
- /**
896
- * Returns metadata for Vercel AI SDK's experimental_telemetry option.
897
- *
898
- * Use this when making Vercel AI SDK calls outside of withSpan() to ensure
899
- * the interaction's properties (userId, convoId, eventId) are attached to the spans.
900
- *
901
- * When using withSpan(), this is handled automatically via context propagation.
902
- * This method is a fallback for cases where you can't use withSpan().
903
- *
904
- * @returns Metadata object with traceloop association properties
905
- *
906
- * @example
907
- * ```typescript
908
- * const interaction = raindrop.begin({ userId: "user-123", convoId: "convo-456" });
909
- *
910
- * // Option 1: Use withSpan (recommended - automatic context propagation)
911
- * await interaction.withSpan("my-task", async () => {
912
- * await generateText({ experimental_telemetry: { isEnabled: true }, ... });
913
- * });
914
- *
915
- * // Option 2: Use vercelAiSdkMetadata (fallback when withSpan isn't possible)
916
- * await generateText({
917
- * experimental_telemetry: {
918
- * isEnabled: true,
919
- * metadata: interaction.vercelAiSdkMetadata(),
920
- * },
921
- * ...
922
- * });
923
- * ```
924
- */
925
- vercelAiSdkMetadata(): Record<string, string>;
926
- /**
927
- * Returns the interaction event ID used for event/signal correlation.
928
- */
929
- getEventId(): string | undefined;
930
- /**
931
- * Logs a tool span directly without wrapping a function.
932
- *
933
- * Use this when you want to record a tool invocation that has already completed,
934
- * rather than wrapping the tool call with withTool(). This is useful for:
935
- * - Recording tool calls from external systems
936
- * - Logging tools that were executed outside of the tracing context
937
- * - Retroactively adding tool spans with known input/output/duration
938
- *
939
- * @param params TrackToolParams object with tool execution details
940
- *
941
- * @example
942
- * ```typescript
943
- * const interaction = raindrop.begin({ userId: "user-123", event: "agent_run" });
944
- *
945
- * // Record a tool that was already executed
946
- * interaction.trackTool({
947
- * name: "web_search",
948
- * input: { query: "weather in NYC" },
949
- * output: { results: ["Sunny, 72°F"] },
950
- * durationMs: 150,
951
- * });
952
- *
953
- * // Record a failed tool
954
- * interaction.trackTool({
955
- * name: "database_query",
956
- * input: { sql: "SELECT * FROM users" },
957
- * error: new Error("Connection timeout"),
958
- * durationMs: 5000,
959
- * });
960
- *
961
- * interaction.finish({ output: "Here's the weather..." });
962
- * ```
963
- */
964
- trackTool(params: TrackToolParams): void;
965
- /**
966
- * Emits a live event to the local debugger for this interaction's trace.
967
- *
968
- * Use this to surface streaming output or framework-specific progress from
969
- * integrations that do not use `@raindrop-ai/ai-sdk`.
970
- */
971
- emitLiveEvent(event: LocalDebuggerLiveEventInput): void;
972
- /**
973
- * Records the launch of a **detached** sub-agent: one that runs in another
974
- * process, does not block this interaction, and reports as its own Raindrop
975
- * event with its own lifecycle.
976
- *
977
- * The child's event id is allocated BEFORE anything is dispatched, so this
978
- * interaction can point at the child from the moment of launch — while the
979
- * job is still queued and before the child has emitted anything. Send the
980
- * returned headers with the job; the worker passes them to
981
- * `raindrop.resumeSubagent()`.
982
- *
983
- * Nothing here waits for the child, and nothing here claims to know how it
984
- * is doing.
985
- *
986
- * @example
987
- * ```typescript
988
- * const dispatch = interaction.subagent({
989
- * name: "researcher",
990
- * input: { task },
991
- * });
992
- * await queue.send({ task, headers: dispatch.headers });
993
- * return { jobId: dispatch.childEventId, status: "accepted" };
994
- * ```
995
- */
996
- subagent(options: SubagentDispatchOptions): SubagentDispatch;
997
- };
998
- type Tracer = {
999
- /**
1000
- * Creates a traced task that executes the provided function.
1001
- *
1002
- * @param params TaskParams object with task configuration
1003
- * @returns A span that can be used to record a task
1004
- */
1005
- withSpan<T>(params: SpanParams, fn: (...args: any[]) => Promise<T> | T, thisArg?: any, ...args: any[]): Promise<T>;
1006
- /**
1007
- * Logs a tool span directly without wrapping a function.
1008
- *
1009
- * Use this when you want to record a tool invocation that has already completed,
1010
- * rather than wrapping the tool call. This is useful for batch jobs or
1011
- * non-interactive use-cases where you only care about tracing and token usage.
1012
- *
1013
- * @param params TrackToolParams object with tool execution details
1014
- *
1015
- * @example
1016
- * ```typescript
1017
- * const tracer = raindrop.tracer({ job_id: "batch-123" });
1018
- *
1019
- * // Record a tool that was already executed
1020
- * tracer.trackTool({
1021
- * name: "web_search",
1022
- * input: { query: "weather in NYC" },
1023
- * output: { results: ["Sunny, 72°F"] },
1024
- * durationMs: 150,
1025
- * });
1026
- * ```
1027
- */
1028
- trackTool(params: TrackToolParams): void;
1029
- /**
1030
- * Emits a live event to the local debugger using the current active trace.
1031
- */
1032
- emitLiveEvent(event: LocalDebuggerLiveEventInput): void;
1033
- };
1034
-
1035
- declare global {
1036
- var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => {
1037
- getStore(): T | undefined;
1038
- run<R>(store: T, callback: () => R): R;
1039
- enterWith?(store: T): void;
1040
- }) | undefined;
1041
- }
1042
-
1043
- /**
1044
- * Internal tracing bootstrap. The entity and processor behaviour is ported
1045
- * from @traceloop/node-server-sdk 0.19.0 (Apache-2.0).
1046
- */
1047
-
1048
- type AllInstrumentationLibraries = "all";
1049
- type InstrumentationModules = Record<string, unknown>;
1050
- interface SpanProcessorOptions {
1051
- apiKey?: string;
1052
- baseUrl?: string;
1053
- disableBatch?: boolean;
1054
- exporter?: SpanExporter;
1055
- headers?: Record<string, string>;
1056
- allowedInstrumentationLibraries?: string[] | AllInstrumentationLibraries;
1057
- }
1058
- interface InitializeOptions extends SpanProcessorOptions {
1059
- appName?: string;
1060
- processor?: SpanProcessor;
1061
- tracingEnabled?: boolean;
1062
- logLevel?: "debug" | "info" | "warn" | "error";
1063
- silenceInitializationMessage?: boolean;
1064
- instrumentModules?: InstrumentationModules;
1065
- contextManager?: ContextManager$1;
1066
- propagator?: TextMapPropagator;
1067
- traceContent?: boolean;
1068
- instrumentations?: Instrumentation[];
1069
- /**
1070
- * Prompt-registry sync options accepted for wrapper compatibility.
1071
- * Raindrop never wired up traceloop's prompt registry, so they are inert.
1072
- */
1073
- traceloopSyncEnabled?: boolean;
1074
- traceloopSyncMaxRetries?: number;
1075
- traceloopSyncPollingInterval?: number;
1076
- traceloopSyncDevPollingInterval?: number;
1077
- }
1078
-
1079
- interface AnalyticsConfig {
1080
- wizardSession?: string;
1081
- /**
1082
- * Raindrop write key. When omitted (or empty), the SDK runs in local-only mode:
1083
- * cloud requests are skipped and only the Workshop / local-debugger mirror fires
1084
- * (when `localWorkshopUrl` resolves to a URL). Useful for local development where
1085
- * you only want events to land in Workshop without provisioning a write key.
1086
- */
1087
- writeKey?: string;
1088
- bufferSize?: number;
1089
- bufferTimeout?: number;
1090
- debugLogs?: boolean;
1091
- endpoint?: string;
1092
- redactPii?: boolean;
1093
- /**
1094
- * Per-field character cap applied to ai input/output and serialized
1095
- * tool/span content BEFORE buffering or serialization, so oversized
1096
- * payloads cost the cap — not the payload — on the calling code path
1097
- * (`JSON.stringify` of a multi-MB payload blocks the event loop).
1098
- * Truncated fields end with `...[truncated by raindrop]` and never exceed
1099
- * the cap, marker included. Defaults to 1,000,000 (matching the Python SDK's
1100
- * `max_text_field_chars`).
1101
- */
1102
- maxTextFieldChars?: number;
1103
- /**
1104
- * Force-enable (or opt out of) Workshop / local-debugger mirroring.
1105
- *
1106
- * - `string` — explicit Workshop URL (e.g. `"http://localhost:5899/v1/"`),
1107
- * wins over env vars and runtime auto-detect.
1108
- * - `false` (or `null`) — explicit opt-out, even on localhost / when
1109
- * `NODE_ENV=development` / when `RAINDROP_WORKSHOP` is set.
1110
- * - `undefined` (default) — fall through to `RAINDROP_LOCAL_DEBUGGER`,
1111
- * `RAINDROP_WORKSHOP`, and runtime auto-detect (localhost-ish hostname
1112
- * OR `NODE_ENV=development` enables the default `:5899` daemon).
1113
- */
1114
- localWorkshopUrl?: string | false | null;
1115
- /**
1116
- * Optional project slug. When set, every outbound cloud ingest request
1117
- * (event POSTs and the direct trace shipper) carries an
1118
- * `X-Raindrop-Project-Id: <projectId>` header so the backend routes the
1119
- * data to that project. Empty / whitespace-only values are ignored and the
1120
- * backend falls back to the account's default project. Slug format is
1121
- * validated on construction but never throws — invalid values are warned
1122
- * about (when `debugLogs` is true) and sent anyway (the backend returns
1123
- * HTTP 400 if the value is actually unusable). Local Workshop mirror
1124
- * requests deliberately skip this header (project routing is a cloud-only
1125
- * concept), mirroring the `@raindrop-ai/core` convention.
1126
- */
1127
- projectId?: string;
1128
- /**
1129
- * @deprecated Renamed to `useExternalOtel`. Use that instead.
1130
- * This option will be removed in a future version.
1131
- */
1132
- disableTracing?: boolean;
1133
- /**
1134
- * Set to true if you have your own OpenTelemetry setup (e.g., Sentry, Datadog).
1135
- *
1136
- * When true:
1137
- * - Raindrop won't create its own NodeSDK (avoids conflicts)
1138
- * - Use `raindrop.createSpanProcessor()` to get a processor for your NodeSDK
1139
- * - Use `raindrop.getInstrumentations()` to get configured LLM instrumentations
1140
- *
1141
- * @example
1142
- * ```ts
1143
- * import { NodeSDK } from "@opentelemetry/sdk-node";
1144
- * import Anthropic from "@anthropic-ai/sdk";
1145
- *
1146
- * const raindrop = new Raindrop({
1147
- * writeKey: "xxx",
1148
- * useExternalOtel: true,
1149
- * instrumentModules: { anthropic: Anthropic },
1150
- * });
1151
- *
1152
- * const sdk = new NodeSDK({
1153
- * spanProcessors: [raindrop.createSpanProcessor(), yourSentryProcessor],
1154
- * instrumentations: raindrop.getInstrumentations(),
1155
- * });
1156
- * sdk.start();
1157
- * ```
1158
- */
1159
- useExternalOtel?: boolean;
1160
- /**
1161
- * false by default. If true, the SDK will not send any events or initialize tracing.
1162
- * Useful for development/test environments.
1163
- */
1164
- disabled?: boolean;
1165
- /**
1166
- * Disable span batching for local development.
1167
- * When true, spans are sent immediately instead of being batched.
1168
- * Defaults to true in development (NODE_ENV !== 'production').
1169
- */
1170
- disableBatching?: boolean;
1171
- /**
1172
- * When true, all `trackTool()`, `withTool()`, and `startToolSpan()` calls bypass the OTEL
1173
- * exporter pipeline and ship spans directly to the Raindrop API via HTTP POST.
1174
- *
1175
- * Spans still read the active OTEL context to inherit traceId
1176
- * and parentSpanId — they still appear as children in the trace tree.
1177
- * Only the shipping mechanism changes.
1178
- *
1179
- * This is useful when OTEL setup is fragile (e.g., conflicting providers,
1180
- * broken exporters) but you still want tool spans to work reliably.
1181
- *
1182
- * @default false
1183
- */
1184
- bypassOtelForTools?: boolean;
1185
- /**
1186
- * Whether `interaction.finish()` should await the in-flight span/trace flush
1187
- * (i.e. `forceFlush()`, which drains buffered OTLP/tool spans — a `/v1/traces`
1188
- * POST with retries) before resolving. This await was added so a local
1189
- * Workshop daemon doesn't race OTLP ingest; in cloud mode it only adds
1190
- * request latency.
1191
- *
1192
- * Note this gates *only* the span flush. `finish()` always awaits the
1193
- * terminal partial-event POST that records the run, and always orders it
1194
- * after any earlier in-flight POST for the same eventId — to skip the
1195
- * partial POST too, simply don't `await interaction.finish(...)`.
1196
- *
1197
- * - `true` / `undefined` (default) — await the span/trace flush, preserving
1198
- * the historical guaranteed-flush-before-return behavior.
1199
- * - `false` — don't await it; it drains in the background so the caller's
1200
- * request isn't taxed by the round trip + retries. A local Workshop /
1201
- * debugger still forces the await regardless (its read-after-write
1202
- * guarantee depends on it).
1203
- */
1204
- awaitSpanFlush?: boolean;
1205
- /**
1206
- * Explicitly specify modules to instrument. Optional.
1207
- *
1208
- * Pass the module constructors/namespaces you want to instrument:
1209
- * @example
1210
- * ```ts
1211
- * import OpenAI from "openai";
1212
- * import Anthropic from "@anthropic-ai/sdk";
1213
- *
1214
- * const raindrop = new Raindrop({
1215
- * writeKey: "xxx",
1216
- * instrumentModules: {
1217
- * openAI: OpenAI,
1218
- * anthropic: Anthropic,
1219
- * },
1220
- * });
1221
- * ```
1222
- */
1223
- instrumentModules?: {
1224
- openAI?: unknown;
1225
- anthropic?: unknown;
1226
- cohere?: unknown;
1227
- bedrock?: unknown;
1228
- google_vertexai?: unknown;
1229
- google_aiplatform?: unknown;
1230
- pinecone?: unknown;
1231
- together?: unknown;
1232
- langchain?: boolean;
1233
- llamaIndex?: unknown;
1234
- chromadb?: unknown;
1235
- qdrant?: unknown;
1236
- mcp?: unknown;
1237
- } & Record<string, unknown>;
1238
- }
1239
- declare const MAX_INGEST_SIZE_BYTES: number;
1240
- /**
1241
- * Resolve the effective `disableBatching` flag that decides whether tracing
1242
- * uses `SimpleSpanProcessor` (immediate export) or `BatchSpanProcessor`.
1243
- *
1244
- * Precedence:
1245
- * 1. An explicit `config.disableBatching` always wins, in both directions.
1246
- * 2. Otherwise, batching is disabled when NOT in production (existing
1247
- * behavior) OR when the local debugger (Workshop) is active — so spans
1248
- * deliver immediately to Workshop even under `NODE_ENV=production`.
1249
- *
1250
- * Production behavior for consumers is unchanged: with no local debugger and
1251
- * no explicit config, this returns `false` (i.e. batching stays on).
1252
- */
1253
- declare function resolveDisableBatching(explicit: boolean | undefined, signals: {
1254
- isProduction: boolean;
1255
- isLocalDebugger: boolean;
1256
- }): boolean;
1257
- declare class Raindrop {
1258
- private wizardSession;
1259
- private writeKey;
1260
- private apiUrl;
1261
- private buffer;
1262
- private bufferSize;
1263
- private bufferTimeout;
1264
- private flushTimer;
1265
- private redactPii;
1266
- private disabled;
1267
- private context;
1268
- private _tracing;
1269
- private localDebuggerUrlOpt;
1270
- private awaitSpanFlushOpt;
1271
- private partialEventBuffer;
1272
- private partialEventTimeouts;
1273
- private inFlightRequests;
1274
- private inFlightByEvent;
1275
- private maxTextFieldChars;
1276
- private projectId;
1277
- private authHint;
1278
- /**
1279
- * Epoch ms deadline while `close()` is draining; undefined otherwise.
1280
- * Checked before every POST issued during the final flush so a dead or
1281
- * slow network can never wedge process exit.
1282
- */
1283
- private shutdownDeadlineAt;
1284
- /**
1285
- * Set once `close()` begins and never cleared. Sends issued after the
1286
- * drain window (stragglers, or flush work the deadline abandoned
1287
- * mid-drain) run as a single short attempt instead of regaining the full
1288
- * retry schedule.
1289
- */
1290
- private hasShutdown;
1291
- debugLogs: boolean;
1292
- constructor(config: AnalyticsConfig);
1293
- private get localOnly();
1294
- private formatEndpoint;
1295
- /**
1296
- * Begins a new interaction.
1297
- *
1298
- * The interaction's routing binding lives until `finish()` (which unbinds it
1299
- * by identity, so it is removed even if `finish()` runs inside a nested
1300
- * `withSpan`/`withTool`/`asCurrent` scope or a detached task). One exception:
1301
- * calling `begin()` INSIDE an `asCurrent(fn)` scope pushes the binding within
1302
- * that scope, so it dies when the scope exits (matching the Python SDK's
1303
- * token-reset semantics) — start such interactions outside `asCurrent`, or
1304
- * keep their work inside the same scope.
1305
- *
1306
- * @param traceContext - The trace context for the interaction.
1307
- * @returns The interaction object.
1308
- */
1309
- begin(traceContext: PartialAiTrackEvent & {
1310
- event: string;
1311
- userId: string;
1312
- }): Interaction;
1313
- /**
1314
- * Returns a tracer object that can be used to create spans and tools that aren't tied to any interaction.
1315
- * For chat interaction use-case `begin` should be used.
1316
- * This is meant for batch jobs or other non-interactive use-cases where you only care about tracing and token usage.
1317
- *
1318
- * @param globalProperties - Optional global properties to be associated with all spans and tools.
1319
- * @returns The tracer object.
1320
- */
1321
- tracer(globalProperties?: Record<string, string>): Tracer;
1322
- /**
1323
- * Scope all spans created inside `fn` (and its awaited continuations) to this
1324
- * client's project/key, without an interaction. Use it around auto-
1325
- * instrumented calls (an LLM SDK call, a framework invocation) that aren't
1326
- * wrapped by `begin()`/`finish()` so their spans route to this client's
1327
- * project in a multi-client process. The binding lasts exactly the duration
1328
- * of `fn` — it is removed when `fn` returns or throws.
1329
- *
1330
- * @example
1331
- * ```ts
1332
- * const answer = await raindrop.asCurrent(() => llm.chat({ ... }));
1333
- * ```
1334
- */
1335
- asCurrent<T>(fn: () => T): T;
1336
- createSpanProcessor(processorOptions?: SpanProcessorOptions): RaindropSpanProcessor;
1337
- /**
1338
- * Returns configured instrumentation instances based on instrumentModules.
1339
- * Add these to your NodeSDK when using useExternalOtel: true.
1340
- *
1341
- * @example
1342
- * ```ts
1343
- * import { NodeSDK } from "@opentelemetry/sdk-node";
1344
- * import Anthropic from "@anthropic-ai/sdk";
1345
- *
1346
- * const raindrop = new Raindrop({
1347
- * writeKey: "xxx",
1348
- * useExternalOtel: true,
1349
- * instrumentModules: { anthropic: Anthropic },
1350
- * });
1351
- *
1352
- * const sdk = new NodeSDK({
1353
- * spanProcessors: [raindrop.createSpanProcessor()],
1354
- * instrumentations: raindrop.getInstrumentations(),
1355
- * });
1356
- * sdk.start();
1357
- * ```
1358
- */
1359
- getInstrumentations(): _opentelemetry_instrumentation.Instrumentation<_opentelemetry_instrumentation.InstrumentationConfig>[];
1360
- /**
1361
- * Resumes an existing interaction.
1362
- *
1363
- * @param eventId - The ID of the interaction to resume.
1364
- * @returns The interaction object.
1365
- */
1366
- resumeInteraction(eventId: string): Interaction;
1367
- /**
1368
- * Opens the child's own event for a launched detached sub-agent.
1369
- *
1370
- * Sibling to {@link resumeInteraction}, and deliberately not the same thing:
1371
- * a resumed interaction JOINS the caller's event, while a detached sub-agent
1372
- * reports as its OWN event under the id the launcher minted, linked back only
1373
- * by the hand-off attributes both sides write. Every span the run emits
1374
- * carries the reverse reference until it reports a result.
1375
- *
1376
- * Pass the headers the request arrived with. A missing carrier is a
1377
- * legitimate state — the sub-agent was invoked directly rather than
1378
- * dispatched — so this always returns a usable run and leaves `parent` null;
1379
- * call sites stay unconditional. A malformed carrier costs the link, never
1380
- * the request.
1381
- *
1382
- * The carrier is authoritative for every identity field it supplies. The
1383
- * options are fallbacks for the direct-invocation case, not overrides: each
1384
- * field names something the launcher already recorded, so a locally minted
1385
- * value winning would strand the child outside the link.
1386
- *
1387
- * > **Trust boundary.** A carrier names the event the child will be
1388
- * > attributed to, so accepting one from an untrusted caller lets that caller
1389
- * > write into another tenant's trace. Only read carriers that came from
1390
- * > inside your own trust boundary.
1391
- *
1392
- * @example
1393
- * ```typescript
1394
- * const run = raindrop.resumeSubagent(request.headers);
1395
- * try {
1396
- * const answer = await doTheWork();
1397
- * await run.finish({ output: answer });
1398
- * } catch (error) {
1399
- * await run.fail(error);
1400
- * }
1401
- * ```
1402
- */
1403
- resumeSubagent(headers: CarrierHeaders | TraceCarrier | null | undefined, options?: SubagentResumeOptions): SubagentRun;
1404
- /**
1405
- * Runs `fn` as a detached sub-agent and guarantees the run reports an
1406
- * outcome, mirroring the Python SDK's `with rd.resume_subagent(...) as run:`.
1407
- *
1408
- * A run that returns without reporting output is closed with an abort reason,
1409
- * and one that throws is failed with it. That is not cosmetic: an event is
1410
- * created only from a run with non-empty output, so a child that dies
1411
- * silently produces no event at all and its launcher stays on `queued`
1412
- * forever — indistinguishable from a job that never started.
1413
- *
1414
- * @example
1415
- * ```typescript
1416
- * await raindrop.withSubagentRun(request.headers, async (run) => {
1417
- * await run.finish({ output: await doTheWork() });
1418
- * });
1419
- * ```
1420
- */
1421
- withSubagentRun<T>(headers: CarrierHeaders | TraceCarrier | null | undefined, fn: (run: SubagentRun) => Promise<T> | T, options?: SubagentResumeOptions): Promise<T>;
1422
- /**
1423
- * Creates a framework-agnostic self-diagnostics tool definition.
1424
- *
1425
- * Use this when your agent framework does not support automatic tool injection.
1426
- * The returned object includes adapters for Vercel AI SDK, OpenAI function tools,
1427
- * and Anthropic tool definitions.
1428
- */
1429
- createSelfDiagnosticsTool(options?: SelfDiagnosticsToolOptions): SelfDiagnosticsTool;
1430
- /**
1431
- * Track AI events. In addiiton to normal event properties, you can provide an "input", "output", or "model" parameter.
1432
- * It takes an AiTrackEvent as input and sends it to the /track-ai endpoint of the raindrop api.
1433
- *
1434
- * @param event - The AiTrackEvent (you must specify at least one of input/output properties)
1435
- * @returns A Promise that resolves when the event has been successfully sent.
1436
- *
1437
- * Example usage:
1438
- * ```typescript
1439
- * raindrop.track_ai({
1440
- * event: "chat", //name of the event
1441
- * model: "claude", //optional
1442
- * input: "what's up?", // input or output is required
1443
- * output: "not much human, how are you?", //input or output is required
1444
- * userId: "cn123456789",
1445
- * });
1446
- * ```
1447
- */
1448
- trackAi(event: AiTrackEvent | AiTrackEvent[]): string | Array<string | undefined> | undefined;
1449
- setUserDetails(event: IdentifyEvent): void;
1450
- /**
1451
- * Report a self-diagnostic signal. This is a convenient shorthand for sending
1452
- * signals that appear in the Self Diagnostics tab of the Raindrop dashboard.
1453
- *
1454
- * @param options - The diagnostic details.
1455
- * @param options.eventId - The interaction/event ID this diagnostic belongs to.
1456
- * @param options.description - A human-readable description of the issue.
1457
- * @param options.category - Optional category (e.g. "missing_context"). Defaults to "general".
1458
- * @param options.source - Optional source identifier. Defaults to "selfDiagnose".
1459
- * @param options.sentiment - Signal sentiment. Defaults to "NEGATIVE".
1460
- * @param options.properties - Additional custom properties.
1461
- *
1462
- * @example
1463
- * ```typescript
1464
- * raindrop.selfDiagnose({
1465
- * eventId: "evt_123",
1466
- * description: "User asked for production DB access but no credentials were provided.",
1467
- * category: "missing_context",
1468
- * });
1469
- * ```
1470
- */
1471
- selfDiagnose(options: SelfDiagnoseOptions): void;
1472
- trackSignal(signal: SignalEvent | SignalEvent[]): void | void[];
1473
- private getSize;
1474
- private saveToBuffer;
1475
- private flush;
1476
- private mirrorBatchToLocalDebugger;
1477
- /**
1478
- * Attempts/timeout budget for one POST, honoring the close() deadline.
1479
- * Returns `null` when the shutdown budget is exhausted — the caller must
1480
- * drop the payload instead of issuing a request that could outlive
1481
- * process exit. Checked fresh on every send so a deadline that expires
1482
- * mid-drain takes effect immediately.
1483
- */
1484
- private requestBudget;
1485
- private warnShutdownDrop;
1486
- private sendBatchToApi;
1487
- private getContext;
1488
- private formatZodError;
1489
- /**
1490
- * Deeply merges properties of the source object into the target object.
1491
- * Modifies the target object in place. Handles nested plain objects.
1492
- */
1493
- private deepMergeObjects;
1494
- /**
1495
- * Internal method for tracking partial AI events. use .begin() to start an interaction instead.
1496
- *
1497
- * @param event - The PartialAiTrackEvent, requires eventId.
1498
- */
1499
- _trackAiPartial(event: PartialAiTrackEvent): Promise<void>;
1500
- /**
1501
- * Flushes a single accumulated partial event by its ID.
1502
- * This is called internally by the timeout or by the close method.
1503
- * @param eventId - The ID of the partial event to flush.
1504
- */
1505
- private flushPartialEvent;
1506
- /**
1507
- * Internal implementation of flushPartialEvent without request tracking.
1508
- * @param eventId - The ID of the partial event to flush.
1509
- */
1510
- private _flushPartialEventInternal;
1511
- /**
1512
- * Sends a single prepared event object to the 'events/track_partial' endpoint.
1513
- * @param event - The event data conforming to ClientAiTrack schema.
1514
- */
1515
- private sendPartialEvent;
1516
- /**
1517
- * Best-effort flush of in-flight OTel spans and pending partial-event POSTs.
1518
- * Safe to call multiple times; never throws.
1519
- */
1520
- forceFlush(): Promise<void>;
1521
- close(): Promise<void>;
1522
- private closeWithinDeadline;
1523
- }
1524
-
1525
- export { type AiTrackUsage as A, type BeginInteractionOptions as B, type CarrierHeaders as C, type SubagentFinishOptions as D, type ToolParams as E, type FinishInteractionOptions as F, type ToolSpan as G, type TraceContext as H, type InitializeOptions as I, type TrackToolParams as J, resolveDisableBatching as K, type LocalDebuggerLiveEventInput as L, MAX_INGEST_SIZE_BYTES as M, type PartialAiTrackEvent as P, Raindrop as R, type SpanProcessorOptions as S, type TraceCarrier as T, type WorkflowParams as W, type RaindropSpanProcessor as a, type Interaction as b, type SubagentResumeOptions as c, type SubagentRun as d, type Tracer as e, type AiTrackEvent as f, type Attachment as g, type AttachmentType as h, type IdentifyEvent as i, type RaindropFeatureFlagValue as j, type RaindropFeatureFlags as k, type RaindropProperties as l, type RaindropPropertyLeaf as m, type RaindropPropertyValue as n, type SelfDiagnoseOptions as o, type SelfDiagnosticsExecuteContext as p, type SelfDiagnosticsExecuteResult as q, type SelfDiagnosticsSignalDefinition as r, type SelfDiagnosticsSignalDefinitions as s, type SelfDiagnosticsTool as t, type SelfDiagnosticsToolInputSchema as u, type SelfDiagnosticsToolOptions as v, type SignalEvent as w, type SpanParams as x, type SubagentDispatch as y, type SubagentDispatchOptions as z };