@raindrop-ai/deep-agents 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/README.md +123 -0
- package/dist/index.d.mts +365 -0
- package/dist/index.d.ts +365 -0
- package/dist/index.js +1245 -0
- package/dist/index.mjs +1217 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# @raindrop-ai/deep-agents
|
|
2
|
+
|
|
3
|
+
Raindrop integration for [LangChain Deep Agents](https://docs.langchain.com/oss/javascript/deepagents/overview). Automatically captures LLM calls, tool usage (planning, filesystem, shell, subagent delegation), chains, and agent actions via LangChain's callback system.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @raindrop-ai/deep-agents @langchain/core deepagents
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { createDeepAgent } from "deepagents";
|
|
15
|
+
import { ChatAnthropic } from "@langchain/anthropic";
|
|
16
|
+
import { createRaindropDeepAgents } from "@raindrop-ai/deep-agents";
|
|
17
|
+
|
|
18
|
+
const raindrop = createRaindropDeepAgents({
|
|
19
|
+
writeKey: "your-write-key",
|
|
20
|
+
userId: "user-123",
|
|
21
|
+
convoId: "session-abc",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const agent = createDeepAgent({
|
|
25
|
+
model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
|
|
26
|
+
tools: [/* filesystem, shell, etc. */],
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const result = await agent.invoke(
|
|
30
|
+
{ messages: [{ role: "user", content: "Create a hello world file" }] },
|
|
31
|
+
{ callbacks: [raindrop.handler] },
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
await raindrop.shutdown();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## What gets captured
|
|
38
|
+
|
|
39
|
+
- **LLM calls**: model name, input, output, token usage (`prompt_tokens`, `completion_tokens`)
|
|
40
|
+
- **Extended token categories**: `ai.usage.cached_tokens` (OpenAI prompt cache hits, Anthropic `cache_read`), `ai.usage.thoughts_tokens` (o1/o3 reasoning tokens) — when reported by the provider
|
|
41
|
+
- **Finish reason**: captured as `ai.finish_reason` in event properties (`"stop"`, `"length"`, `"tool_calls"`, `"content_filter"`, etc.)
|
|
42
|
+
- **Tool calls**: tool name (`write_todos`, `read_file`, `write_file`, `edit_file`, `ls`, `glob`, `grep`, `execute`, `task`), input, output
|
|
43
|
+
- **Chains**: execution spans with parent-child nesting
|
|
44
|
+
- **Agent actions**: tool selection and finish events
|
|
45
|
+
- **Multi-modal messages**: typed-parts content (`[{type: "text", text: "..."}, ...]`) is extracted cleanly — text-type parts are concatenated; non-text parts (images, audio) are skipped
|
|
46
|
+
- **Errors**: captured with `error.type` + `error.message` properties and `[Error] ...` output on the event, plus OTLP error status on the span
|
|
47
|
+
|
|
48
|
+
## Options
|
|
49
|
+
|
|
50
|
+
| Option | Type | Default | Description |
|
|
51
|
+
|--------|------|---------|-------------|
|
|
52
|
+
| `writeKey` | `string` | - | Raindrop API write key (omit to disable telemetry) |
|
|
53
|
+
| `endpoint` | `string` | `https://api.raindrop.ai/v1/` | API endpoint |
|
|
54
|
+
| `userId` | `string` | - | Associate all events with a user |
|
|
55
|
+
| `convoId` | `string` | - | Group events into a conversation |
|
|
56
|
+
| `debug` | `boolean` | `false` | Enable verbose logging |
|
|
57
|
+
| `traceChains` | `boolean` | `true` | Create spans for chain execution |
|
|
58
|
+
|
|
59
|
+
## LangGraph Support
|
|
60
|
+
|
|
61
|
+
Deep Agents is built on LangGraph. The handler automatically:
|
|
62
|
+
- Filters LangGraph-internal chain events (`__start__`, `__end__`, `ChannelWrite:*`, `ChannelRead:*`, `Branch:*`) — the colon is part of LangGraph's naming convention, user-defined chains whose names happen to start with "Branch" (e.g. `BranchRouter`) are NOT filtered
|
|
63
|
+
- Keeps the root `LangGraph` chain so the OTel association context is in place before any inner span fires (filtering it orphans all downstream spans)
|
|
64
|
+
- Deduplicates LLM callbacks that LangGraph fires multiple times with the same `runId`
|
|
65
|
+
- Links parent-child spans for chain→LLM→tool hierarchies
|
|
66
|
+
|
|
67
|
+
## API Surface
|
|
68
|
+
|
|
69
|
+
The `createRaindropDeepAgents()` factory returns:
|
|
70
|
+
|
|
71
|
+
- `handler` — LangChain `BaseCallbackHandler` to pass via `config.callbacks`
|
|
72
|
+
- `lastEventId` — `event_id` of the most recently finalized root event (or `undefined` if none has landed). Use this to attach a follow-up `signals.track()` to the agent invocation you just ran without polling the dashboard. Example:
|
|
73
|
+
```typescript
|
|
74
|
+
await agent.invoke({ messages: [...] }, { callbacks: [raindrop.handler] });
|
|
75
|
+
if (raindrop.lastEventId) {
|
|
76
|
+
await raindrop.signals.track({
|
|
77
|
+
eventId: raindrop.lastEventId,
|
|
78
|
+
name: "thumbs_up",
|
|
79
|
+
type: "feedback",
|
|
80
|
+
sentiment: "POSITIVE",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
- `events.patch(eventId, patch)` — update event properties
|
|
85
|
+
- `events.finish(eventId, patch)` — finalize an event
|
|
86
|
+
- `events.addAttachments(eventId, attachments)` — attach files/text to an event
|
|
87
|
+
- `events.setProperties(eventId, properties)` — set custom properties
|
|
88
|
+
- `users.identify(users)` — identify users with traits
|
|
89
|
+
- `signals.track(signal)` — track user signals/feedback
|
|
90
|
+
- `flush()` — flush pending telemetry
|
|
91
|
+
- `shutdown()` — flush and close connections
|
|
92
|
+
|
|
93
|
+
## Known Limitations
|
|
94
|
+
|
|
95
|
+
- **Beta status**: API surface may change in future releases.
|
|
96
|
+
- **Deep Agents version**: Requires `deepagents >= 0.5.0`.
|
|
97
|
+
- **Streaming**: Token-by-token streaming events are not captured individually; only the final aggregated response is tracked.
|
|
98
|
+
- **Subagent isolation**: When using the `task` tool for subagent delegation, each subagent's callbacks fire independently.
|
|
99
|
+
- **Concurrent invocations on a shared handler**: A single handler instance keeps one in-flight span map at a time. Running multiple `agent.invoke(...)` calls **concurrently with the same handler** (e.g. `Promise.all([agent.invoke(...), agent.invoke(...)])` with the same `raindrop.handler`) can scramble the linkage between events and traces. Instantiate one `createRaindropDeepAgents()` per concurrent request; sequential invocations on a shared handler are fully supported.
|
|
100
|
+
- **Long chain inputs/outputs are truncated**: Chain-level `input` and `output` captured on the root event are truncated to ~8 KB to stay within the SDK's payload-size limit. Per-LLM child events still carry full prompts.
|
|
101
|
+
|
|
102
|
+
## Testing
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Unit tests (no external services; use MSW to intercept HTTP)
|
|
106
|
+
pnpm test -- tests/handler.test.ts
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**E2E tests** run REAL Deep Agents workflows via `createDeepAgent()` against a REAL LLM (OpenAI gpt-4o-mini) and verify events / tool calls / traces against the production dashboard TRPC API. They skip automatically when any of `RAINDROP_WRITE_KEY`, `OPENAI_API_KEY`, or `RAINDROP_DASHBOARD_TOKEN` is missing.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# E2E — requires all three keys
|
|
113
|
+
RAINDROP_WRITE_KEY=xxx \
|
|
114
|
+
OPENAI_API_KEY=sk-... \
|
|
115
|
+
RAINDROP_DASHBOARD_TOKEN=eyJ... \
|
|
116
|
+
pnpm test -- tests/e2e.test.ts
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The dashboard token comes from `app.raindrop.ai` → DevTools → Network → any `backend.raindrop.ai` request → `Authorization: Bearer ...` (expires every ~30 min, so grab a fresh one immediately before running).
|
|
120
|
+
|
|
121
|
+
## Python
|
|
122
|
+
|
|
123
|
+
A Python version of this integration is available as `raindrop-deep-agents` on PyPI. See [the Python package](https://github.com/invisible-tools/dawn/tree/main/packages/deep-agents-python) for details.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
|
+
import { Serialized } from '@langchain/core/load/serializable';
|
|
3
|
+
import { LLMResult } from '@langchain/core/outputs';
|
|
4
|
+
import { BaseMessage } from '@langchain/core/messages';
|
|
5
|
+
import { AgentAction, AgentFinish } from '@langchain/core/agents';
|
|
6
|
+
import { ChainValues } from '@langchain/core/utils/types';
|
|
7
|
+
|
|
8
|
+
type OtlpAnyValue = {
|
|
9
|
+
stringValue?: string;
|
|
10
|
+
intValue?: string;
|
|
11
|
+
doubleValue?: number;
|
|
12
|
+
boolValue?: boolean;
|
|
13
|
+
arrayValue?: {
|
|
14
|
+
values: OtlpAnyValue[];
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type OtlpKeyValue = {
|
|
18
|
+
key: string;
|
|
19
|
+
value: OtlpAnyValue;
|
|
20
|
+
};
|
|
21
|
+
declare const SpanStatusCode: {
|
|
22
|
+
readonly UNSET: 0;
|
|
23
|
+
readonly OK: 1;
|
|
24
|
+
readonly ERROR: 2;
|
|
25
|
+
};
|
|
26
|
+
type OtlpSpanStatus = {
|
|
27
|
+
code: (typeof SpanStatusCode)[keyof typeof SpanStatusCode] | number;
|
|
28
|
+
message?: string;
|
|
29
|
+
};
|
|
30
|
+
type OtlpSpan = {
|
|
31
|
+
traceId: string;
|
|
32
|
+
spanId: string;
|
|
33
|
+
parentSpanId?: string;
|
|
34
|
+
name: string;
|
|
35
|
+
startTimeUnixNano: string;
|
|
36
|
+
endTimeUnixNano: string;
|
|
37
|
+
attributes?: OtlpKeyValue[];
|
|
38
|
+
status?: OtlpSpanStatus;
|
|
39
|
+
};
|
|
40
|
+
type SpanIds = {
|
|
41
|
+
traceIdB64: string;
|
|
42
|
+
spanIdB64: string;
|
|
43
|
+
parentSpanIdB64?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type Attachment = {
|
|
47
|
+
type: string;
|
|
48
|
+
role: string;
|
|
49
|
+
name?: string;
|
|
50
|
+
value: string;
|
|
51
|
+
};
|
|
52
|
+
type IdentifyInput = {
|
|
53
|
+
userId: string;
|
|
54
|
+
traits?: Record<string, unknown>;
|
|
55
|
+
};
|
|
56
|
+
type Patch = {
|
|
57
|
+
eventName?: string;
|
|
58
|
+
userId?: string;
|
|
59
|
+
convoId?: string;
|
|
60
|
+
input?: string;
|
|
61
|
+
output?: string;
|
|
62
|
+
model?: string;
|
|
63
|
+
properties?: Record<string, unknown>;
|
|
64
|
+
attachments?: Attachment[];
|
|
65
|
+
isPending?: boolean;
|
|
66
|
+
timestamp?: string;
|
|
67
|
+
};
|
|
68
|
+
type SignalInput = {
|
|
69
|
+
eventId: string;
|
|
70
|
+
name: string;
|
|
71
|
+
type?: "default" | "feedback" | "edit" | "standard" | "agent" | "agent_internal";
|
|
72
|
+
sentiment?: "POSITIVE" | "NEGATIVE";
|
|
73
|
+
timestamp?: string;
|
|
74
|
+
properties?: Record<string, unknown>;
|
|
75
|
+
attachmentId?: string;
|
|
76
|
+
comment?: string;
|
|
77
|
+
after?: string;
|
|
78
|
+
};
|
|
79
|
+
type EventShipperOptions = {
|
|
80
|
+
writeKey?: string;
|
|
81
|
+
endpoint?: string;
|
|
82
|
+
enabled?: boolean;
|
|
83
|
+
debug: boolean;
|
|
84
|
+
partialFlushMs?: number;
|
|
85
|
+
sdkName?: string;
|
|
86
|
+
libraryName?: string;
|
|
87
|
+
libraryVersion?: string;
|
|
88
|
+
defaultEventName?: string;
|
|
89
|
+
};
|
|
90
|
+
declare class EventShipper {
|
|
91
|
+
private baseUrl;
|
|
92
|
+
private writeKey?;
|
|
93
|
+
private enabled;
|
|
94
|
+
private debug;
|
|
95
|
+
private partialFlushMs;
|
|
96
|
+
private sdkName;
|
|
97
|
+
private prefix;
|
|
98
|
+
private defaultEventName;
|
|
99
|
+
private context;
|
|
100
|
+
private buffers;
|
|
101
|
+
private sticky;
|
|
102
|
+
private timers;
|
|
103
|
+
private inFlight;
|
|
104
|
+
constructor(opts: EventShipperOptions);
|
|
105
|
+
isDebugEnabled(): boolean;
|
|
106
|
+
private authHeaders;
|
|
107
|
+
patch(eventId: string, patch: Patch): Promise<void>;
|
|
108
|
+
finish(eventId: string, patch: {
|
|
109
|
+
output?: string;
|
|
110
|
+
model?: string;
|
|
111
|
+
properties?: Record<string, unknown>;
|
|
112
|
+
userId?: string;
|
|
113
|
+
}): Promise<void>;
|
|
114
|
+
flush(): Promise<void>;
|
|
115
|
+
shutdown(): Promise<void>;
|
|
116
|
+
trackSignal(signal: SignalInput): Promise<void>;
|
|
117
|
+
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
118
|
+
private flushOne;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
type InternalSpan = {
|
|
122
|
+
ids: SpanIds;
|
|
123
|
+
name: string;
|
|
124
|
+
startTimeUnixNano: string;
|
|
125
|
+
endTimeUnixNano?: string;
|
|
126
|
+
attributes: Array<OtlpKeyValue | undefined>;
|
|
127
|
+
};
|
|
128
|
+
type TraceShipperOptions = {
|
|
129
|
+
writeKey?: string;
|
|
130
|
+
endpoint?: string;
|
|
131
|
+
enabled?: boolean;
|
|
132
|
+
debug: boolean;
|
|
133
|
+
debugSpans?: boolean;
|
|
134
|
+
flushIntervalMs?: number;
|
|
135
|
+
maxBatchSize?: number;
|
|
136
|
+
maxQueueSize?: number;
|
|
137
|
+
sdkName?: string;
|
|
138
|
+
serviceName?: string;
|
|
139
|
+
serviceVersion?: string;
|
|
140
|
+
};
|
|
141
|
+
declare class TraceShipper {
|
|
142
|
+
private baseUrl;
|
|
143
|
+
private writeKey?;
|
|
144
|
+
private enabled;
|
|
145
|
+
private debug;
|
|
146
|
+
private debugSpans;
|
|
147
|
+
private sdkName;
|
|
148
|
+
private prefix;
|
|
149
|
+
private serviceName;
|
|
150
|
+
private serviceVersion;
|
|
151
|
+
private flushIntervalMs;
|
|
152
|
+
private maxBatchSize;
|
|
153
|
+
private maxQueueSize;
|
|
154
|
+
private queue;
|
|
155
|
+
private timer;
|
|
156
|
+
private inFlight;
|
|
157
|
+
/** URL of the local debugger (from RAINDROP_LOCAL_DEBUGGER env var). */
|
|
158
|
+
private localDebuggerUrl;
|
|
159
|
+
constructor(opts: TraceShipperOptions);
|
|
160
|
+
isDebugEnabled(): boolean;
|
|
161
|
+
private authHeaders;
|
|
162
|
+
startSpan(args: {
|
|
163
|
+
name: string;
|
|
164
|
+
parent?: {
|
|
165
|
+
traceIdB64: string;
|
|
166
|
+
spanIdB64: string;
|
|
167
|
+
};
|
|
168
|
+
eventId: string;
|
|
169
|
+
operationId?: string;
|
|
170
|
+
attributes?: Array<OtlpKeyValue | undefined>;
|
|
171
|
+
startTimeUnixNano?: string;
|
|
172
|
+
}): InternalSpan;
|
|
173
|
+
endSpan(span: InternalSpan, extra?: {
|
|
174
|
+
attributes?: InternalSpan["attributes"];
|
|
175
|
+
error?: unknown;
|
|
176
|
+
status?: OtlpSpanStatus;
|
|
177
|
+
endTimeUnixNano?: string;
|
|
178
|
+
}): void;
|
|
179
|
+
createSpan(args: {
|
|
180
|
+
name: string;
|
|
181
|
+
parent?: {
|
|
182
|
+
traceIdB64: string;
|
|
183
|
+
spanIdB64: string;
|
|
184
|
+
};
|
|
185
|
+
eventId: string;
|
|
186
|
+
startTimeUnixNano: string;
|
|
187
|
+
endTimeUnixNano: string;
|
|
188
|
+
attributes?: Array<OtlpKeyValue | undefined>;
|
|
189
|
+
status?: OtlpSpanStatus;
|
|
190
|
+
}): void;
|
|
191
|
+
enqueue(span: OtlpSpan): void;
|
|
192
|
+
flush(): Promise<void>;
|
|
193
|
+
shutdown(): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
type ParentSpanContext = {
|
|
197
|
+
traceIdB64: string;
|
|
198
|
+
spanIdB64: string;
|
|
199
|
+
eventId: string;
|
|
200
|
+
};
|
|
201
|
+
interface ContextSpan {
|
|
202
|
+
readonly traceIdB64: string;
|
|
203
|
+
readonly spanIdB64: string;
|
|
204
|
+
readonly eventId: string;
|
|
205
|
+
log?(data: Record<string, unknown>): void;
|
|
206
|
+
}
|
|
207
|
+
interface AsyncLocalStorageLike<T> {
|
|
208
|
+
getStore(): T | undefined;
|
|
209
|
+
run<R>(store: T, callback: () => R): R;
|
|
210
|
+
enterWith?(store: T): void;
|
|
211
|
+
}
|
|
212
|
+
declare abstract class ContextManager {
|
|
213
|
+
abstract getParentSpanIds(): ParentSpanContext | undefined;
|
|
214
|
+
abstract runInContext<R>(span: ContextSpan, callback: () => R): R;
|
|
215
|
+
abstract getCurrentSpan(): ContextSpan | undefined;
|
|
216
|
+
abstract isReady(): boolean;
|
|
217
|
+
}
|
|
218
|
+
declare global {
|
|
219
|
+
var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
|
|
220
|
+
var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
interface RaindropDeepAgentsHandlerOptions {
|
|
224
|
+
eventShipper: EventShipper;
|
|
225
|
+
traceShipper: TraceShipper;
|
|
226
|
+
userId?: string;
|
|
227
|
+
convoId?: string;
|
|
228
|
+
traceChains?: boolean;
|
|
229
|
+
}
|
|
230
|
+
declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
|
|
231
|
+
name: string;
|
|
232
|
+
private eventShipper;
|
|
233
|
+
private traceShipper;
|
|
234
|
+
private userId?;
|
|
235
|
+
private convoId?;
|
|
236
|
+
private traceChains;
|
|
237
|
+
private spans;
|
|
238
|
+
private rootRunIds;
|
|
239
|
+
private eventIds;
|
|
240
|
+
private forwardedSpans;
|
|
241
|
+
/**
|
|
242
|
+
* event_id of the most recently finalized ROOT event. Exposed via
|
|
243
|
+
* ``RaindropDeepAgentsClient.lastEventId`` so callers can attach a
|
|
244
|
+
* follow-up signal to the agent invocation they just ran without
|
|
245
|
+
* polling the dashboard. Persists across runs; not reset on cleanup.
|
|
246
|
+
*/
|
|
247
|
+
_lastRootEventId: string | undefined;
|
|
248
|
+
constructor(opts: RaindropDeepAgentsHandlerOptions);
|
|
249
|
+
private getEventId;
|
|
250
|
+
private getParent;
|
|
251
|
+
private cleanup;
|
|
252
|
+
private finalizeEventIfRoot;
|
|
253
|
+
handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
|
|
254
|
+
handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
|
|
255
|
+
handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string): Promise<void>;
|
|
256
|
+
handleLLMError(err: unknown, runId: string): Promise<void>;
|
|
257
|
+
handleChainStart(chain: Serialized, _inputs: ChainValues, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record<string, unknown>, _runType?: string, runName?: string): Promise<void>;
|
|
258
|
+
handleChainEnd(_outputs: ChainValues, runId: string): Promise<void>;
|
|
259
|
+
handleChainError(err: unknown, runId: string): Promise<void>;
|
|
260
|
+
handleToolStart(tool: Serialized, input: string, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record<string, unknown>, runName?: string): Promise<void>;
|
|
261
|
+
handleToolEnd(output: unknown, runId: string): Promise<void>;
|
|
262
|
+
handleToolError(err: unknown, runId: string): Promise<void>;
|
|
263
|
+
handleAgentAction(action: AgentAction, runId: string, parentRunId?: string): Promise<void>;
|
|
264
|
+
handleAgentEnd(_action: AgentFinish, runId: string): Promise<void>;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
interface DeepAgentsOptions {
|
|
268
|
+
/**
|
|
269
|
+
* API write key. If omitted, telemetry shipping is disabled but the handler
|
|
270
|
+
* is still available for a consistent integration surface.
|
|
271
|
+
*/
|
|
272
|
+
writeKey?: string;
|
|
273
|
+
endpoint?: string;
|
|
274
|
+
debug?: boolean;
|
|
275
|
+
userId?: string;
|
|
276
|
+
convoId?: string;
|
|
277
|
+
traceChains?: boolean;
|
|
278
|
+
}
|
|
279
|
+
type RaindropDeepAgentsClient = {
|
|
280
|
+
/**
|
|
281
|
+
* LangChain callback handler to pass to Deep Agents via `config.callbacks`.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const raindrop = createRaindropDeepAgents({ writeKey: "..." });
|
|
286
|
+
* const agent = createDeepAgent({ tools: [...] });
|
|
287
|
+
* const result = await agent.invoke(
|
|
288
|
+
* { messages: [{ role: "user", content: "Hello" }] },
|
|
289
|
+
* { callbacks: [raindrop.handler] },
|
|
290
|
+
* );
|
|
291
|
+
* await raindrop.shutdown();
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
handler: RaindropDeepAgentsHandler;
|
|
295
|
+
/**
|
|
296
|
+
* `event_id` of the most recently finalized ROOT event, or `undefined`
|
|
297
|
+
* if no root event has landed yet. Use this to attach a feedback
|
|
298
|
+
* `signals.track()` to the agent invocation you just ran, without
|
|
299
|
+
* having to poll the dashboard for the real id.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const raindrop = createRaindropDeepAgents({ writeKey: "..." });
|
|
304
|
+
* await agent.invoke({ messages: [...] }, { callbacks: [raindrop.handler] });
|
|
305
|
+
* if (raindrop.lastEventId) {
|
|
306
|
+
* await raindrop.signals.track({
|
|
307
|
+
* eventId: raindrop.lastEventId,
|
|
308
|
+
* name: "thumbs_up",
|
|
309
|
+
* type: "feedback",
|
|
310
|
+
* sentiment: "POSITIVE",
|
|
311
|
+
* });
|
|
312
|
+
* }
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
readonly lastEventId: string | undefined;
|
|
316
|
+
events: {
|
|
317
|
+
patch(eventId: string, patch: Patch): Promise<void>;
|
|
318
|
+
finish(eventId: string, patch: {
|
|
319
|
+
output?: string;
|
|
320
|
+
model?: string;
|
|
321
|
+
properties?: Record<string, unknown>;
|
|
322
|
+
}): Promise<void>;
|
|
323
|
+
addAttachments(eventId: string, attachments: Attachment[]): Promise<void>;
|
|
324
|
+
setProperties(eventId: string, properties: Record<string, unknown>): Promise<void>;
|
|
325
|
+
};
|
|
326
|
+
users: {
|
|
327
|
+
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
328
|
+
};
|
|
329
|
+
signals: {
|
|
330
|
+
track(signal: SignalInput): Promise<void>;
|
|
331
|
+
};
|
|
332
|
+
flush(): Promise<void>;
|
|
333
|
+
shutdown(): Promise<void>;
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* Create a Raindrop client for instrumenting LangChain Deep Agents.
|
|
337
|
+
*
|
|
338
|
+
* Deep Agents is built on LangChain and LangGraph. This integration provides
|
|
339
|
+
* a callback handler that captures LLM calls, tool usage (write_todos,
|
|
340
|
+
* read_file, write_file, edit_file, task, execute, etc.), chains, and agent
|
|
341
|
+
* actions — shipping them to Raindrop for observability.
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```typescript
|
|
345
|
+
* import { createDeepAgent } from "deepagents";
|
|
346
|
+
* import { createRaindropDeepAgents } from "@raindrop-ai/deep-agents";
|
|
347
|
+
*
|
|
348
|
+
* const raindrop = createRaindropDeepAgents({
|
|
349
|
+
* writeKey: process.env.RAINDROP_API_KEY,
|
|
350
|
+
* userId: "user-123",
|
|
351
|
+
* convoId: "convo-456",
|
|
352
|
+
* });
|
|
353
|
+
*
|
|
354
|
+
* const agent = createDeepAgent({ tools: [myTool] });
|
|
355
|
+
* const result = await agent.invoke(
|
|
356
|
+
* { messages: [{ role: "user", content: "Research LangGraph" }] },
|
|
357
|
+
* { callbacks: [raindrop.handler] },
|
|
358
|
+
* );
|
|
359
|
+
*
|
|
360
|
+
* await raindrop.shutdown();
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
declare function createRaindropDeepAgents(opts: DeepAgentsOptions): RaindropDeepAgentsClient;
|
|
364
|
+
|
|
365
|
+
export { type DeepAgentsOptions, type RaindropDeepAgentsClient, RaindropDeepAgentsHandler, createRaindropDeepAgents };
|