@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.
- package/LICENSE +47 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +117 -0
- package/dist/bin.js.map +1 -0
- package/dist/src/docs/browser.md +105 -0
- package/dist/src/docs/python.md +618 -0
- package/dist/src/docs/typescript.md +584 -0
- package/dist/src/docs/vercel-ai-sdk.md +304 -0
- package/dist/src/lib/agent-interface.d.ts +46 -0
- package/dist/src/lib/agent-interface.js +292 -0
- package/dist/src/lib/agent-interface.js.map +1 -0
- package/dist/src/lib/agent-prompts.d.ts +10 -0
- package/dist/src/lib/agent-prompts.js +49 -0
- package/dist/src/lib/agent-prompts.js.map +1 -0
- package/dist/src/lib/config.d.ts +39 -0
- package/dist/src/lib/config.js +549 -0
- package/dist/src/lib/config.js.map +1 -0
- package/dist/src/lib/constants.d.ts +27 -0
- package/dist/src/lib/constants.js +165 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/handlers.d.ts +68 -0
- package/dist/src/lib/handlers.js +420 -0
- package/dist/src/lib/handlers.js.map +1 -0
- package/dist/src/lib/integration-testing.d.ts +44 -0
- package/dist/src/lib/integration-testing.js +123 -0
- package/dist/src/lib/integration-testing.js.map +1 -0
- package/dist/src/lib/mcp.d.ts +14 -0
- package/dist/src/lib/mcp.js +134 -0
- package/dist/src/lib/mcp.js.map +1 -0
- package/dist/src/lib/sdk-messages.d.ts +17 -0
- package/dist/src/lib/sdk-messages.js +278 -0
- package/dist/src/lib/sdk-messages.js.map +1 -0
- package/dist/src/lib/wizard.d.ts +6 -0
- package/dist/src/lib/wizard.js +131 -0
- package/dist/src/lib/wizard.js.map +1 -0
- package/dist/src/run.d.ts +8 -0
- package/dist/src/run.js +53 -0
- package/dist/src/run.js.map +1 -0
- package/dist/src/ui/App.d.ts +15 -0
- package/dist/src/ui/App.js +27 -0
- package/dist/src/ui/App.js.map +1 -0
- package/dist/src/ui/cancellation.d.ts +14 -0
- package/dist/src/ui/cancellation.js +17 -0
- package/dist/src/ui/cancellation.js.map +1 -0
- package/dist/src/ui/components/ClarifyingQuestionsPrompt.d.ts +17 -0
- package/dist/src/ui/components/ClarifyingQuestionsPrompt.js +359 -0
- package/dist/src/ui/components/ClarifyingQuestionsPrompt.js.map +1 -0
- package/dist/src/ui/components/ContinuePrompt.d.ts +14 -0
- package/dist/src/ui/components/ContinuePrompt.js +23 -0
- package/dist/src/ui/components/ContinuePrompt.js.map +1 -0
- package/dist/src/ui/components/DiffDisplay.d.ts +18 -0
- package/dist/src/ui/components/DiffDisplay.js +110 -0
- package/dist/src/ui/components/DiffDisplay.js.map +1 -0
- package/dist/src/ui/components/FeedbackSelectPrompt.d.ts +20 -0
- package/dist/src/ui/components/FeedbackSelectPrompt.js +132 -0
- package/dist/src/ui/components/FeedbackSelectPrompt.js.map +1 -0
- package/dist/src/ui/components/HistoryItemDisplay.d.ts +14 -0
- package/dist/src/ui/components/HistoryItemDisplay.js +140 -0
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -0
- package/dist/src/ui/components/Logo.d.ts +10 -0
- package/dist/src/ui/components/Logo.js +47 -0
- package/dist/src/ui/components/Logo.js.map +1 -0
- package/dist/src/ui/components/OrgInfoBox.d.ts +11 -0
- package/dist/src/ui/components/OrgInfoBox.js +16 -0
- package/dist/src/ui/components/OrgInfoBox.js.map +1 -0
- package/dist/src/ui/components/PendingPrompt.d.ts +18 -0
- package/dist/src/ui/components/PendingPrompt.js +57 -0
- package/dist/src/ui/components/PendingPrompt.js.map +1 -0
- package/dist/src/ui/components/PersistentTextInput.d.ts +21 -0
- package/dist/src/ui/components/PersistentTextInput.js +117 -0
- package/dist/src/ui/components/PersistentTextInput.js.map +1 -0
- package/dist/src/ui/components/PlanApprovalPrompt.d.ts +19 -0
- package/dist/src/ui/components/PlanApprovalPrompt.js +62 -0
- package/dist/src/ui/components/PlanApprovalPrompt.js.map +1 -0
- package/dist/src/ui/components/PromptContainer.d.ts +14 -0
- package/dist/src/ui/components/PromptContainer.js +18 -0
- package/dist/src/ui/components/PromptContainer.js.map +1 -0
- package/dist/src/ui/components/SelectPrompt.d.ts +14 -0
- package/dist/src/ui/components/SelectPrompt.js +62 -0
- package/dist/src/ui/components/SelectPrompt.js.map +1 -0
- package/dist/src/ui/components/SpinnerDisplay.d.ts +13 -0
- package/dist/src/ui/components/SpinnerDisplay.js +11 -0
- package/dist/src/ui/components/SpinnerDisplay.js.map +1 -0
- package/dist/src/ui/components/ToolApprovalPrompt.d.ts +14 -0
- package/dist/src/ui/components/ToolApprovalPrompt.js +142 -0
- package/dist/src/ui/components/ToolApprovalPrompt.js.map +1 -0
- package/dist/src/ui/components/ToolCallDisplay.d.ts +14 -0
- package/dist/src/ui/components/ToolCallDisplay.js +83 -0
- package/dist/src/ui/components/ToolCallDisplay.js.map +1 -0
- package/dist/src/ui/components/WriteKeyDisplay.d.ts +15 -0
- package/dist/src/ui/components/WriteKeyDisplay.js +13 -0
- package/dist/src/ui/components/WriteKeyDisplay.js.map +1 -0
- package/dist/src/ui/contexts/WizardContext.d.ts +210 -0
- package/dist/src/ui/contexts/WizardContext.js +362 -0
- package/dist/src/ui/contexts/WizardContext.js.map +1 -0
- package/dist/src/ui/hooks/useCancellation.d.ts +15 -0
- package/dist/src/ui/hooks/useCancellation.js +25 -0
- package/dist/src/ui/hooks/useCancellation.js.map +1 -0
- package/dist/src/ui/render.d.ts +34 -0
- package/dist/src/ui/render.js +94 -0
- package/dist/src/ui/render.js.map +1 -0
- package/dist/src/ui/types.d.ts +184 -0
- package/dist/src/ui/types.js +6 -0
- package/dist/src/ui/types.js.map +1 -0
- package/dist/src/utils/clack-utils.d.ts +13 -0
- package/dist/src/utils/clack-utils.js +131 -0
- package/dist/src/utils/clack-utils.js.map +1 -0
- package/dist/src/utils/debug.d.ts +13 -0
- package/dist/src/utils/debug.js +47 -0
- package/dist/src/utils/debug.js.map +1 -0
- package/dist/src/utils/environment.d.ts +5 -0
- package/dist/src/utils/environment.js +131 -0
- package/dist/src/utils/environment.js.map +1 -0
- package/dist/src/utils/logging.d.ts +9 -0
- package/dist/src/utils/logging.js +38 -0
- package/dist/src/utils/logging.js.map +1 -0
- package/dist/src/utils/oauth.d.ts +12 -0
- package/dist/src/utils/oauth.js +497 -0
- package/dist/src/utils/oauth.js.map +1 -0
- package/dist/src/utils/package-json-types.d.ts +44 -0
- package/dist/src/utils/package-json-types.js +6 -0
- package/dist/src/utils/package-json-types.js.map +1 -0
- package/dist/src/utils/package-json.d.ts +19 -0
- package/dist/src/utils/package-json.js +22 -0
- package/dist/src/utils/package-json.js.map +1 -0
- package/dist/src/utils/session.d.ts +2 -0
- package/dist/src/utils/session.js +87 -0
- package/dist/src/utils/session.js.map +1 -0
- package/dist/src/utils/types.d.ts +61 -0
- package/dist/src/utils/types.js +2 -0
- package/dist/src/utils/types.js.map +1 -0
- package/dist/src/utils/ui.d.ts +120 -0
- package/dist/src/utils/ui.js +164 -0
- package/dist/src/utils/ui.js.map +1 -0
- 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.
|