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