@raindrop-ai/wizard 0.0.1

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.
Files changed (135) hide show
  1. package/LICENSE +47 -0
  2. package/dist/bin.d.ts +2 -0
  3. package/dist/bin.js +117 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/src/docs/browser.md +105 -0
  6. package/dist/src/docs/python.md +618 -0
  7. package/dist/src/docs/typescript.md +584 -0
  8. package/dist/src/docs/vercel-ai-sdk.md +304 -0
  9. package/dist/src/lib/agent-interface.d.ts +46 -0
  10. package/dist/src/lib/agent-interface.js +292 -0
  11. package/dist/src/lib/agent-interface.js.map +1 -0
  12. package/dist/src/lib/agent-prompts.d.ts +10 -0
  13. package/dist/src/lib/agent-prompts.js +49 -0
  14. package/dist/src/lib/agent-prompts.js.map +1 -0
  15. package/dist/src/lib/config.d.ts +39 -0
  16. package/dist/src/lib/config.js +549 -0
  17. package/dist/src/lib/config.js.map +1 -0
  18. package/dist/src/lib/constants.d.ts +27 -0
  19. package/dist/src/lib/constants.js +165 -0
  20. package/dist/src/lib/constants.js.map +1 -0
  21. package/dist/src/lib/handlers.d.ts +68 -0
  22. package/dist/src/lib/handlers.js +420 -0
  23. package/dist/src/lib/handlers.js.map +1 -0
  24. package/dist/src/lib/integration-testing.d.ts +44 -0
  25. package/dist/src/lib/integration-testing.js +123 -0
  26. package/dist/src/lib/integration-testing.js.map +1 -0
  27. package/dist/src/lib/mcp.d.ts +14 -0
  28. package/dist/src/lib/mcp.js +134 -0
  29. package/dist/src/lib/mcp.js.map +1 -0
  30. package/dist/src/lib/sdk-messages.d.ts +17 -0
  31. package/dist/src/lib/sdk-messages.js +278 -0
  32. package/dist/src/lib/sdk-messages.js.map +1 -0
  33. package/dist/src/lib/wizard.d.ts +6 -0
  34. package/dist/src/lib/wizard.js +131 -0
  35. package/dist/src/lib/wizard.js.map +1 -0
  36. package/dist/src/run.d.ts +8 -0
  37. package/dist/src/run.js +53 -0
  38. package/dist/src/run.js.map +1 -0
  39. package/dist/src/ui/App.d.ts +15 -0
  40. package/dist/src/ui/App.js +27 -0
  41. package/dist/src/ui/App.js.map +1 -0
  42. package/dist/src/ui/cancellation.d.ts +14 -0
  43. package/dist/src/ui/cancellation.js +17 -0
  44. package/dist/src/ui/cancellation.js.map +1 -0
  45. package/dist/src/ui/components/ClarifyingQuestionsPrompt.d.ts +17 -0
  46. package/dist/src/ui/components/ClarifyingQuestionsPrompt.js +359 -0
  47. package/dist/src/ui/components/ClarifyingQuestionsPrompt.js.map +1 -0
  48. package/dist/src/ui/components/ContinuePrompt.d.ts +14 -0
  49. package/dist/src/ui/components/ContinuePrompt.js +23 -0
  50. package/dist/src/ui/components/ContinuePrompt.js.map +1 -0
  51. package/dist/src/ui/components/DiffDisplay.d.ts +18 -0
  52. package/dist/src/ui/components/DiffDisplay.js +110 -0
  53. package/dist/src/ui/components/DiffDisplay.js.map +1 -0
  54. package/dist/src/ui/components/FeedbackSelectPrompt.d.ts +20 -0
  55. package/dist/src/ui/components/FeedbackSelectPrompt.js +132 -0
  56. package/dist/src/ui/components/FeedbackSelectPrompt.js.map +1 -0
  57. package/dist/src/ui/components/HistoryItemDisplay.d.ts +14 -0
  58. package/dist/src/ui/components/HistoryItemDisplay.js +140 -0
  59. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -0
  60. package/dist/src/ui/components/Logo.d.ts +10 -0
  61. package/dist/src/ui/components/Logo.js +47 -0
  62. package/dist/src/ui/components/Logo.js.map +1 -0
  63. package/dist/src/ui/components/OrgInfoBox.d.ts +11 -0
  64. package/dist/src/ui/components/OrgInfoBox.js +16 -0
  65. package/dist/src/ui/components/OrgInfoBox.js.map +1 -0
  66. package/dist/src/ui/components/PendingPrompt.d.ts +18 -0
  67. package/dist/src/ui/components/PendingPrompt.js +57 -0
  68. package/dist/src/ui/components/PendingPrompt.js.map +1 -0
  69. package/dist/src/ui/components/PersistentTextInput.d.ts +21 -0
  70. package/dist/src/ui/components/PersistentTextInput.js +117 -0
  71. package/dist/src/ui/components/PersistentTextInput.js.map +1 -0
  72. package/dist/src/ui/components/PlanApprovalPrompt.d.ts +19 -0
  73. package/dist/src/ui/components/PlanApprovalPrompt.js +62 -0
  74. package/dist/src/ui/components/PlanApprovalPrompt.js.map +1 -0
  75. package/dist/src/ui/components/PromptContainer.d.ts +14 -0
  76. package/dist/src/ui/components/PromptContainer.js +18 -0
  77. package/dist/src/ui/components/PromptContainer.js.map +1 -0
  78. package/dist/src/ui/components/SelectPrompt.d.ts +14 -0
  79. package/dist/src/ui/components/SelectPrompt.js +62 -0
  80. package/dist/src/ui/components/SelectPrompt.js.map +1 -0
  81. package/dist/src/ui/components/SpinnerDisplay.d.ts +13 -0
  82. package/dist/src/ui/components/SpinnerDisplay.js +11 -0
  83. package/dist/src/ui/components/SpinnerDisplay.js.map +1 -0
  84. package/dist/src/ui/components/ToolApprovalPrompt.d.ts +14 -0
  85. package/dist/src/ui/components/ToolApprovalPrompt.js +142 -0
  86. package/dist/src/ui/components/ToolApprovalPrompt.js.map +1 -0
  87. package/dist/src/ui/components/ToolCallDisplay.d.ts +14 -0
  88. package/dist/src/ui/components/ToolCallDisplay.js +83 -0
  89. package/dist/src/ui/components/ToolCallDisplay.js.map +1 -0
  90. package/dist/src/ui/components/WriteKeyDisplay.d.ts +15 -0
  91. package/dist/src/ui/components/WriteKeyDisplay.js +13 -0
  92. package/dist/src/ui/components/WriteKeyDisplay.js.map +1 -0
  93. package/dist/src/ui/contexts/WizardContext.d.ts +210 -0
  94. package/dist/src/ui/contexts/WizardContext.js +362 -0
  95. package/dist/src/ui/contexts/WizardContext.js.map +1 -0
  96. package/dist/src/ui/hooks/useCancellation.d.ts +15 -0
  97. package/dist/src/ui/hooks/useCancellation.js +25 -0
  98. package/dist/src/ui/hooks/useCancellation.js.map +1 -0
  99. package/dist/src/ui/render.d.ts +34 -0
  100. package/dist/src/ui/render.js +94 -0
  101. package/dist/src/ui/render.js.map +1 -0
  102. package/dist/src/ui/types.d.ts +184 -0
  103. package/dist/src/ui/types.js +6 -0
  104. package/dist/src/ui/types.js.map +1 -0
  105. package/dist/src/utils/clack-utils.d.ts +13 -0
  106. package/dist/src/utils/clack-utils.js +131 -0
  107. package/dist/src/utils/clack-utils.js.map +1 -0
  108. package/dist/src/utils/debug.d.ts +13 -0
  109. package/dist/src/utils/debug.js +47 -0
  110. package/dist/src/utils/debug.js.map +1 -0
  111. package/dist/src/utils/environment.d.ts +5 -0
  112. package/dist/src/utils/environment.js +131 -0
  113. package/dist/src/utils/environment.js.map +1 -0
  114. package/dist/src/utils/logging.d.ts +9 -0
  115. package/dist/src/utils/logging.js +38 -0
  116. package/dist/src/utils/logging.js.map +1 -0
  117. package/dist/src/utils/oauth.d.ts +12 -0
  118. package/dist/src/utils/oauth.js +497 -0
  119. package/dist/src/utils/oauth.js.map +1 -0
  120. package/dist/src/utils/package-json-types.d.ts +44 -0
  121. package/dist/src/utils/package-json-types.js +6 -0
  122. package/dist/src/utils/package-json-types.js.map +1 -0
  123. package/dist/src/utils/package-json.d.ts +19 -0
  124. package/dist/src/utils/package-json.js +22 -0
  125. package/dist/src/utils/package-json.js.map +1 -0
  126. package/dist/src/utils/session.d.ts +2 -0
  127. package/dist/src/utils/session.js +87 -0
  128. package/dist/src/utils/session.js.map +1 -0
  129. package/dist/src/utils/types.d.ts +61 -0
  130. package/dist/src/utils/types.js +2 -0
  131. package/dist/src/utils/types.js.map +1 -0
  132. package/dist/src/utils/ui.d.ts +120 -0
  133. package/dist/src/utils/ui.js +164 -0
  134. package/dist/src/utils/ui.js.map +1 -0
  135. package/package.json +140 -0
@@ -0,0 +1,584 @@
1
+ ---
2
+ description: TypeScript SDK reference for tracking events and AI interactions.
3
+ title: 'TypeScript'
4
+ ---
5
+
6
+ ## Installation
7
+
8
+ Install using the project's package manager:
9
+
10
+ <CodeGroup>
11
+
12
+ ```bash npm
13
+ npm install raindrop-ai
14
+ ```
15
+
16
+ ```bash yarn
17
+ yarn add raindrop-ai
18
+ ```
19
+
20
+ ```bash bun
21
+ bun add raindrop-ai
22
+ ```
23
+
24
+ </CodeGroup>
25
+
26
+ ```typescript
27
+ import { Raindrop } from 'raindrop-ai';
28
+
29
+ // RAINDROP_WRITE_KEY should have already been loaded from environment variables
30
+ const raindrop = new Raindrop({
31
+ writeKey: process.env.RAINDROP_WRITE_KEY,
32
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
33
+ });
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Quick Start: Interaction API
39
+
40
+ The Interaction API uses a simple three-step pattern:
41
+
42
+ 1. **`begin()`** – Create an interaction and log the initial user input
43
+ 2. **Update** – Optionally call `setProperty`, `setProperties`, or
44
+ `addAttachments`
45
+ 3. **`finish()`** – Record the AI's final output and close the interaction
46
+
47
+ ### Example: Chat Completion
48
+
49
+ ```typescript
50
+ import { openai } from '@ai-sdk/openai';
51
+ import { generateText } from 'ai';
52
+ // UUID generation: check the project's existing approach first.
53
+ // - If the project already uses a UUID library (e.g. 'uuid'), use that.
54
+ // - If using Next.js with Turbopack, use crypto.randomUUID() or the 'uuid' package — Turbopack does not polyfill Node built-ins.
55
+ // - Otherwise, `import { randomUUID } from 'crypto'` is fine for Node.js servers (webpack, esbuild, etc. handle it).
56
+ import { randomUUID } from 'crypto';
57
+ import { Raindrop } from 'raindrop-ai';
58
+
59
+ const raindrop = new Raindrop({
60
+ writeKey: process.env.RAINDROP_WRITE_KEY,
61
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
62
+ });
63
+
64
+ const eventId = randomUUID(); // Only generate if the app doesn't already have an event ID
65
+
66
+ // 1. Start the interaction — use actual values from your app
67
+ const interaction = raindrop.begin({
68
+ eventId,
69
+ event: eventName, // A descriptive name for this AI action (e.g. 'chat_message', 'code_generation')
70
+ userId: userId, // The authenticated user's unique identifier from your app
71
+ input: userMessage, // The actual user message/prompt
72
+ model: modelName, // The model being called (e.g. 'gpt-4o')
73
+ convoId: conversationId, // Your app's conversation/thread ID (if applicable)
74
+ properties: { // Optional: any custom metadata relevant to your app
75
+ system_prompt: systemPrompt,
76
+ },
77
+ });
78
+
79
+ // 2. Make the LLM call
80
+ const { text } = await generateText({
81
+ model: openai('gpt-4o'),
82
+ prompt: userMessage,
83
+ });
84
+
85
+ // 3. Finish the interaction
86
+ interaction.finish({
87
+ output: text,
88
+ });
89
+ ```
90
+
91
+ ### Updating an Interaction
92
+
93
+ Update an interaction at any point using `setProperty`, `setProperties`, or
94
+ `addAttachments`:
95
+
96
+ ```typescript
97
+ interaction.setProperty('stage', 'embedding');
98
+ interaction.addAttachments([
99
+ {
100
+ type: 'text',
101
+ name: 'Additional Info',
102
+ value: 'A very long document',
103
+ role: 'input',
104
+ },
105
+ { type: 'image', value: 'https://example.com/image.png', role: 'output' },
106
+ {
107
+ type: 'iframe',
108
+ name: 'Generated UI',
109
+ value: 'https://newui.generated.com',
110
+ role: 'output',
111
+ },
112
+ ]);
113
+ ```
114
+
115
+ ### Resuming an Interaction
116
+
117
+ To resume an interaction without the original object returned from `begin()`,
118
+ use `resumeInteraction()`:
119
+
120
+ ```typescript
121
+ const interaction = raindrop.resumeInteraction(eventId);
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Single-Shot Tracking (`trackAi`)
127
+
128
+ For simple request-response interactions, you can use `trackAi()` directly:
129
+
130
+ Note: `input` and `output` should be the actual prompt sent to and response
131
+ received from your AI model - not literal placeholder strings.
132
+
133
+ ```typescript
134
+ raindrop.trackAi({
135
+ event: eventName, // A descriptive name for this AI action (e.g. 'chat_message', 'code_generation')
136
+ userId: userId, // The authenticated user's unique identifier from your app
137
+ model: modelName, // The model being called (e.g. 'gpt-4o-mini')
138
+ input: userPrompt, // The actual prompt sent to the model
139
+ output: modelResponse, // The actual response from the model
140
+ properties: { // Optional: any custom metadata relevant to your app
141
+ system_prompt: systemPrompt,
142
+ tool_call: toolName,
143
+ },
144
+ });
145
+ ```
146
+
147
+ > Prefer `begin()` → `finish()` for new code to enable partial-event buffering,
148
+ > tracing, and automatic token counts.
149
+
150
+ ---
151
+
152
+ ## Tracking Signals (Feedback)
153
+
154
+ Signals capture quality ratings on AI events. Use `trackSignal()` with the same
155
+ `eventId` from `begin()` or `trackAi()`:
156
+
157
+ | Parameter | Type | Description |
158
+ | ----------- | ---------------------------------------- | ------------------------------------------- |
159
+ | `eventId` | `string` | The ID of the AI event being evaluated |
160
+ | `name` | `"thumbs_up"`, `"thumbs_down"`, `string` | Signal name |
161
+ | `type` | `"default"`, `"feedback"`, `"edit"` | Optional, defaults to `"default"` |
162
+ | `comment` | `string` | User comment (for `feedback` signals) |
163
+ | `after` | `string` | User's edited content (for `edit` signals) |
164
+ | `sentiment` | `"POSITIVE"`, `"NEGATIVE"` | Signal sentiment (defaults to `"NEGATIVE"`) |
165
+
166
+ ```typescript
167
+ await raindrop.trackSignal({
168
+ eventId: eventId, // The ID of the AI event being rated (from begin() or trackAi())
169
+ name: 'thumbs_down',
170
+ comment: userComment, // The user's feedback comment
171
+ });
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Attachments
177
+
178
+ Attachments include additional context (documents, images, code, or embedded
179
+ content) with events. Compatible with both `begin()` interactions and
180
+ `trackAi()` calls.
181
+
182
+ | Property | Type | Description |
183
+ | ---------- | -------- | --------------------------------------------- |
184
+ | `type` | `string` | `"code"`, `"text"`, `"image"`, or `"iframe"` |
185
+ | `name` | `string` | Optional display name |
186
+ | `value` | `string` | Content or URL |
187
+ | `role` | `string` | `"input"` or `"output"` |
188
+ | `language` | `string` | Programming language (for `code` attachments) |
189
+
190
+ ```typescript
191
+ interaction.addAttachments([
192
+ {
193
+ type: 'code',
194
+ role: 'input',
195
+ language: 'typescript',
196
+ name: 'example.ts',
197
+ value: "console.log('hello');",
198
+ },
199
+ {
200
+ type: 'text',
201
+ name: 'Additional Info',
202
+ value: 'Some extra text',
203
+ role: 'input',
204
+ },
205
+ { type: 'image', value: 'https://example.com/image.png', role: 'output' },
206
+ { type: 'iframe', value: 'https://example.com/embed', role: 'output' },
207
+ ]);
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Identifying Users
213
+
214
+ ```typescript
215
+ // Pass actual user data from your app's auth/session
216
+ raindrop.setUserDetails({
217
+ userId: userId, // The authenticated user's unique identifier
218
+ traits: { // Pass any user traits available in your app — all keys are optional and freeform
219
+ name: userName,
220
+ email: userEmail,
221
+ },
222
+ });
223
+ ```
224
+
225
+ ---
226
+
227
+ ## PII Redaction
228
+
229
+ Enable client-side PII redaction when initializing the SDK:
230
+
231
+ ```typescript
232
+ new Raindrop({
233
+ writeKey: process.env.RAINDROP_WRITE_KEY,
234
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
235
+ redactPii: true,
236
+ });
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Error Handling
242
+
243
+ Exceptions are raised when errors occur while sending events. Implement
244
+ appropriate error handling in the application.
245
+
246
+ ---
247
+
248
+ ## Configuration
249
+
250
+ ```typescript
251
+ new Raindrop({
252
+ writeKey: process.env.RAINDROP_WRITE_KEY,
253
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
254
+ debugLogs: process.env.NODE_ENV !== 'production', // Print queued events
255
+ disabled: process.env.NODE_ENV === 'test', // Disable all tracking
256
+ });
257
+ ```
258
+
259
+ Call `await raindrop.close()` before the process exits to flush buffered events.
260
+
261
+ ---
262
+
263
+ ## Tracing
264
+
265
+ Tracing captures detailed execution information from AI pipelines including
266
+ multi-model interactions, chained prompts, and tool calls.
267
+
268
+ ### Getting Started
269
+
270
+ Wrap code with `withSpan` or `withTool` on an interaction. LLM calls inside are
271
+ automatically captured:
272
+
273
+ ```typescript
274
+ import { Raindrop } from "raindrop-ai";
275
+
276
+ const raindrop = new Raindrop({
277
+ writeKey: process.env.RAINDROP_WRITE_KEY,
278
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
279
+ });
280
+
281
+ const interaction = raindrop.begin({ ... });
282
+ await interaction.withSpan({ name: "my_task" }, async () => {
283
+ // LLM calls here are automatically traced
284
+ });
285
+ ```
286
+
287
+ **Next.js users:** Add `raindrop-ai` to
288
+ [`serverExternalPackages`](https://nextjs.org/docs/app/api-reference/config/next-config-js/serverExternalPackages)
289
+ in your config:
290
+
291
+ ```typescript
292
+ // next.config.js
293
+ /** @type {import('next').NextConfig} */
294
+ const nextConfig = {
295
+ serverExternalPackages: ['raindrop-ai'],
296
+ };
297
+
298
+ module.exports = nextConfig;
299
+ ```
300
+
301
+ ### Using `withSpan`
302
+
303
+ Use `withSpan` to trace tasks or operations. Any LLM calls within the span are
304
+ automatically captured:
305
+
306
+ ```typescript
307
+ // Basic span
308
+ const result = await interaction.withSpan(
309
+ { name: 'generate_response' },
310
+ async () => {
311
+ return 'Generated response';
312
+ },
313
+ );
314
+
315
+ // Span with metadata
316
+ const result = await interaction.withSpan(
317
+ {
318
+ name: 'embedding_generation',
319
+ properties: { model: 'text-embedding-3-large' },
320
+ inputParameters: ['What is the weather today?'],
321
+ },
322
+ async () => {
323
+ return [0.1, 0.2, 0.3, 0.4];
324
+ },
325
+ );
326
+ ```
327
+
328
+ | Parameter | Type | Description |
329
+ | ----------------- | ------------------------ | --------------------------------- |
330
+ | `name` | `string` | Name for identification in traces |
331
+ | `properties` | `Record<string, string>` | Additional metadata |
332
+ | `inputParameters` | `unknown[]` | Input parameters for the task |
333
+
334
+ ### Using `withTool`
335
+
336
+ Use `withTool` to trace agent actions—memory operations, web searches, API
337
+ calls, and more:
338
+
339
+ ```typescript
340
+ // Basic tool call
341
+ const result = await interaction.withTool({ name: 'search_tool' }, async () => {
342
+ return 'Search results';
343
+ });
344
+
345
+ // Tool with metadata
346
+ const result = await interaction.withTool(
347
+ {
348
+ name: 'calculator',
349
+ properties: { operation: 'multiply' },
350
+ inputParameters: { a: 5, b: 10 },
351
+ },
352
+ async () => {
353
+ return 'Result: 50';
354
+ },
355
+ );
356
+ ```
357
+
358
+ | Parameter | Type | Description |
359
+ | ----------------- | ------------------------ | ------------------------------------ |
360
+ | `name` | `string` | Name for identification in traces |
361
+ | `version` | `number` | Version number of the tool |
362
+ | `properties` | `Record<string, string>` | Additional metadata |
363
+ | `inputParameters` | `Record<string, any>` | Input parameters for the tool |
364
+ | `traceContent` | `boolean` | Whether to trace content |
365
+ | `suppressTracing` | `boolean` | Suppress tracing for this invocation |
366
+
367
+ ### Manual Tool Tracking
368
+
369
+ For more control over tool span tracking, use `trackTool` or `startToolSpan`.
370
+
371
+ #### `trackTool` – Retroactive Logging
372
+
373
+ Use `trackTool` to log a tool call after it has completed:
374
+
375
+ ```typescript
376
+ const interaction = raindrop.begin({
377
+ eventId: eventId,
378
+ event: eventName, // A descriptive name for this AI action (e.g. 'chat_message', 'agent_run')
379
+ userId: userId, // The authenticated user's unique identifier from your app
380
+ input: userQuery, // The actual user input
381
+ });
382
+
383
+ // Log a completed tool call (pass actual tool inputs/outputs)
384
+ interaction.trackTool({
385
+ name: 'web_search',
386
+ input: toolInput, // The actual input passed to the tool
387
+ output: toolOutput, // The actual output returned by the tool
388
+ durationMs: 150,
389
+ properties: { engine: 'google' },
390
+ });
391
+
392
+ // Log a failed tool call
393
+ interaction.trackTool({
394
+ name: 'database_query',
395
+ input: { query: 'SELECT * FROM users' },
396
+ durationMs: 50,
397
+ error: new Error('Connection timeout'),
398
+ });
399
+
400
+ interaction.finish({ output: finalResponse }); // The actual model response
401
+ ```
402
+
403
+ | Parameter | Type | Description |
404
+ | ------------ | ------------------------ | ------------------------------------------------------ |
405
+ | `name` | `string` | Name of the tool |
406
+ | `input` | `unknown` | Input passed to the tool |
407
+ | `output` | `unknown` | Output returned by the tool |
408
+ | `durationMs` | `number` | Duration in milliseconds |
409
+ | `startTime` | `Date \| number` | When the tool started (defaults to `now - durationMs`) |
410
+ | `error` | `Error \| string` | Error if the tool failed |
411
+ | `properties` | `Record<string, string>` | Additional metadata |
412
+
413
+ #### `startToolSpan` – Real-Time Tracking
414
+
415
+ Use `startToolSpan` to track a tool as it executes:
416
+
417
+ ```typescript
418
+ const interaction = raindrop.begin({
419
+ eventId: eventId,
420
+ event: eventName, // A descriptive name for this AI action (e.g. 'chat_message', 'agent_run')
421
+ userId: userId, // The authenticated user's unique identifier from your app
422
+ input: userInput, // The actual user input
423
+ });
424
+
425
+ const toolSpan = interaction.startToolSpan({
426
+ name: 'api_call',
427
+ properties: { endpoint: '/api/data' },
428
+ inputParameters: { method: 'GET', path: '/api/data' },
429
+ });
430
+
431
+ try {
432
+ const result = await fetchData();
433
+ toolSpan.setOutput(result); // Pass actual tool output
434
+ } catch (error) {
435
+ toolSpan.setError(error);
436
+ } finally {
437
+ toolSpan.end();
438
+ }
439
+
440
+ interaction.finish({ output: finalResponse }); // The actual model response
441
+ ```
442
+
443
+ | Method | Description |
444
+ | ------------------- | ------------------------------------------------ |
445
+ | `setInput(input)` | Set the input (JSON stringified if object) |
446
+ | `setOutput(output)` | Set the output (JSON stringified if object) |
447
+ | `setError(error)` | Mark the span as failed |
448
+ | `end()` | End the span (required when execution completes) |
449
+
450
+ ### Module Instrumentation
451
+
452
+ If automatic instrumentation fails due to module loading order or bundler
453
+ behavior, use `instrumentModules` to explicitly specify modules to instrument:
454
+
455
+ <Warning>
456
+ **Anthropic users:** You must use a module namespace import (`import * as ...`), not the default export.
457
+ </Warning>
458
+
459
+ ```typescript
460
+ import OpenAI from 'openai';
461
+ import Anthropic from '@anthropic-ai/sdk';
462
+ import * as AnthropicModule from '@anthropic-ai/sdk'; // Required for instrumentation
463
+ import { Raindrop } from 'raindrop-ai';
464
+
465
+ const raindrop = new Raindrop({
466
+ writeKey: process.env.RAINDROP_WRITE_KEY,
467
+ wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
468
+ instrumentModules: {
469
+ openAI: OpenAI,
470
+ anthropic: AnthropicModule, // Pass the module namespace, not the default export
471
+ },
472
+ });
473
+ ```
474
+
475
+ Supported modules: `openAI`, `anthropic`, `cohere`, `bedrock`,
476
+ `google_vertexai`, `google_aiplatform`, `pinecone`, `together`, `langchain`,
477
+ `llamaIndex`, `chromadb`, `qdrant`, `mcp`.
478
+
479
+ ### External OpenTelemetry Integration
480
+
481
+ For projects with an existing OpenTelemetry setup (Sentry, Datadog, Honeycomb,
482
+ etc.), integrate Raindrop alongside it using `useExternalOtel: true`.
483
+
484
+ **Package version:**
485
+
486
+ - If using OTEL v2: `npm install raindrop-ai@otelv2`
487
+ - If using OTEL v1 (or Sentry < 10): `npm install raindrop-ai`
488
+
489
+ #### With Sentry
490
+
491
+ ```typescript
492
+ import * as Sentry from '@sentry/node';
493
+ import { Raindrop } from 'raindrop-ai';
494
+
495
+ // 1. Create Raindrop with useExternalOtel
496
+ const raindrop = new Raindrop({
497
+ writeKey: process.env.RAINDROP_WRITE_KEY,
498
+ wizardSession: '__WIZARD_SESSION_UUID__',
499
+ useExternalOtel: true, // ⬅️ REQUIRED
500
+ });
501
+
502
+ // 2. Add Raindrop processor to Sentry.init
503
+ Sentry.init({
504
+ dsn: process.env.SENTRY_DSN, // Your project's Sentry DSN
505
+ tracesSampleRate: 1.0,
506
+ openTelemetrySpanProcessors: [
507
+ raindrop.createSpanProcessor(), // ⬅️ Add Raindrop processor
508
+ ],
509
+ });
510
+ ```
511
+
512
+ #### With Other OTEL Providers (Datadog, etc.)
513
+
514
+ > Example uses `@anthropic-ai/sdk`. Adapt imports and `instrumentModules` to the
515
+ > project's AI SDK.
516
+
517
+ ```typescript
518
+ import { NodeSDK } from '@opentelemetry/sdk-node';
519
+ import * as AnthropicModule from '@anthropic-ai/sdk'; // ← Adapt to project's AI SDK
520
+ import { Raindrop } from 'raindrop-ai';
521
+
522
+ // 1. Create Raindrop with useExternalOtel
523
+ const raindrop = new Raindrop({
524
+ writeKey: process.env.RAINDROP_WRITE_KEY,
525
+ wizardSession: '__WIZARD_SESSION_UUID__',
526
+ useExternalOtel: true, // ⬅️ REQUIRED
527
+ instrumentModules: { anthropic: AnthropicModule }, // ← Adapt to project's AI SDK
528
+ });
529
+
530
+ // 2. Add Raindrop to your NodeSDK
531
+ const sdk = new NodeSDK({
532
+ serviceName: projectName, // Replace with your app/service name
533
+ spanProcessors: [
534
+ raindrop.createSpanProcessor(), // Sends to Raindrop
535
+ yourExistingProcessor, // Your existing processor
536
+ ],
537
+ instrumentations: raindrop.getInstrumentations(), // Returns all if instrumentModules not specified
538
+ });
539
+ sdk.start();
540
+ ```
541
+
542
+ #### Usage (Both)
543
+
544
+ > Adapt AI client import and usage to the project's AI SDK.
545
+
546
+ After setup, create AI clients and use Raindrop. For NodeSDK, create clients
547
+ **after** `sdk.start()`.
548
+
549
+ ```typescript
550
+ import Anthropic from '@anthropic-ai/sdk'; // ← Adapt to project's AI SDK
551
+
552
+ const anthropic = new Anthropic({ apiKey: '...' });
553
+
554
+ // LLM calls are auto-captured
555
+ // Note: input and output should be actual model I/O from your app, not placeholder strings
556
+ const interaction = raindrop.begin({
557
+ eventId: eventId,
558
+ event: eventName, // A descriptive name for this AI action
559
+ userId: userId, // The authenticated user's unique identifier from your app
560
+ input: userMessage, // The actual user input
561
+ });
562
+ const response = await interaction.withSpan({ name: 'gen' }, async () => {
563
+ return await anthropic.messages.create({
564
+ // ← Adapt to project's AI SDK
565
+ model: 'claude-3-haiku-20240307', // Replace with the actual model name used in your project
566
+ max_tokens: 100,
567
+ messages: [{ role: 'user', content: userMessage }],
568
+ });
569
+ });
570
+ interaction.finish({ output: response.content[0].text }); // The actual model response
571
+ ```
572
+
573
+ **Key methods:**
574
+
575
+ - `createSpanProcessor()` - Returns processor for NodeSDK or Sentry
576
+ - `getInstrumentations()` - Returns instrumentations for all supported libraries
577
+ (or only those in `instrumentModules` if specified)
578
+
579
+ ---
580
+
581
+ ## Troubleshooting
582
+
583
+ - Interactions are subject to a 1 MB event limit. Oversized payloads will be
584
+ truncated.