@raindrop-ai/claude-managed-agents
v0.0.13
Published
Claude Managed Agents integration for Raindrop
Maintainers
Keywords
Readme
@raindrop-ai/claude-managed-agents
Raindrop integration for Anthropic's Claude Managed Agents. Automatically captures events, traces, and tool call spans from managed agent sessions.
Installation
npm install @raindrop-ai/claude-managed-agents @anthropic-ai/sdkQuick Start
import Anthropic from "@anthropic-ai/sdk";
import { createRaindropClaudeManagedAgents } from "@raindrop-ai/claude-managed-agents";
const client = new Anthropic();
const raindrop = createRaindropClaudeManagedAgents({
writeKey: process.env.RAINDROP_WRITE_KEY, // Optional — omitting disables telemetry
userId: "user-123",
});
const wrapped = raindrop.wrap(client);
const session = await wrapped.beta.sessions.create({
agent: agentId,
environment_id: envId,
title: "My session",
});
const stream = await wrapped.beta.sessions.events.stream(session.id);
await wrapped.beta.sessions.events.send(session.id, {
events: [{ type: "user.message", content: [{ type: "text", text: "Hello" }] }],
});
for await (const event of stream) {
if (event.type === "agent.message") {
for (const block of event.content) {
process.stdout.write(block.text);
}
} else if (event.type === "session.status_idle") {
break;
}
}
await raindrop.shutdown();Shared client options
createRaindropClaudeManagedAgents(...) also takes the options every Raindrop JS integration shares:
| Option | Type | Default | Description |
|---|---|---|---|
| maxTextFieldChars | number | 1000000 | Per-field character cap for captured text |
| redactPii | boolean | false | Redact PII (emails, phone numbers, card numbers, addresses, secrets) from event input/output before it leaves the process |
| redactPiiFields | PiiFieldMap | - | More wire field paths to redact when redactPii is on, e.g. { event: ["properties.customer.email"] }; add properties["error.message"] to also redact error messages |
| flushTimeoutMs | number | 10000 | Deadline for flush() / shutdown(). Both resolve to a result (delivered, dropped, queued, ...) and never reject |
flush() and shutdown() resolve to { delivered, timedOut, dropped, queued, inFlight } and never reject; ignoring the result is fine.
Projects
If your org has multiple projects, route events to a specific one by passing its slug as projectId:
const raindrop = createRaindropClaudeManagedAgents({
writeKey: process.env.RAINDROP_WRITE_KEY,
projectId: "support-prod",
});This sets the X-Raindrop-Project-Id header on every event and trace. Omit it (or pass "default") to use your org's default Production project — the existing behavior. Single-project orgs need nothing new.
Tool catalog capture (ai.prompt.tools)
Agent configuration, not exact per-call capture. Model calls run inside
Anthropic's managed runtime, so the wrapper never sees individual requests.
It does see the resolved agent definition returned by sessions.create()
(session.agent.tools) and records it as ai.prompt.tools on every
managed_agent.session span (one per model turn), together with
ai.prompt.tools.source = "agent.config" so consumers can tell this
configuration snapshot from exact capture. Custom tools keep their
input_schema intact; agent_toolset_20260401 / mcp_toolset entries are
provider-owned and recorded as {"type":"provider-defined",…} without an
invented schema. Absent attribute = catalog unknown; [] = the agent has no
tools. This package has no separate prompt-content switch, so the attribute is
recorded whenever tracing is enabled.
| Option | Description |
| --- | --- |
| tools (on createRaindropClaudeManagedAgents({ tools }) or wrap(client, { tools })) | Overrides the tool catalog recorded as ai.prompt.tools on every model span. Use when the integration cannot see the tools the model was given. Replaces the agent definition entirely (tools: [] records an empty catalog) and carries no source attribute. |
Payload size limits
Text fields (session input/output, span tool payloads) are capped at
1,000,000 characters per field and truncated with a
...[truncated by raindrop] marker. The cap is enforced before (or during)
serialization, so oversized payloads cost the cap — not the payload — on your
event loop, and large events land truncated instead of being rejected at the
ingest size limit.
Turn attachments and per-call context
Image blocks (base64) and plain-text document blocks in a user.message sent
through beta.sessions.events.send become the turn's input attachments (a
document's title is its name). Wrap events.send in
raindrop.withContext({ attachments, properties }, () => ...) to add more
attachments or caller properties to that turn's event. Attachments need type
and role; entries without them are dropped.
Model spans and token usage
The session span carries gen_ai.provider.name (anthropic), the model, and the turn's raw counters summed over its model requests (gen_ai.usage.input_tokens, output_tokens, cache_read_input_tokens, cache_write_input_tokens).
Your properties win
Properties you pass (as defaults, per call, or through events.setProperties / events.patch / events.finish) are merged into the event. If one of your keys has the same name as a key the integration sets itself, such as ai.usage.*, ai.provider, error.type / error.message, or the integration's own prefixed keys, your value is kept, whatever order the updates are sent in. With debug on, the integration logs each key you override.
Event ids
Pass your own id for a turn with raindrop.withContext({ eventId }, ...). The first turn opens at session create, so wrap beta.sessions.create(...) for it; wrap beta.sessions.events.send(...) for each later turn; the event and every span of the turn carry it. Use a fresh id per turn. After a turn finishes, raindrop.lastEventId holds its id, for attaching a signal or feedback:
await raindrop.signals.track({ eventId: raindrop.lastEventId!, name: "thumbs_up", type: "feedback", sentiment: "POSITIVE" });Finishes you make through raindrop.events.* don't change lastEventId. It holds the last turn finished anywhere in the process, so on a client shared by concurrent turns, use the id you passed instead.
Documentation
Full documentation with configuration options, signals, user identification, and more:
docs.raindrop.ai/integrations/claude-managed-agents
License
MIT
Application Git identity
Set appGit on createRaindropClaudeManagedAgents to override commitSha, commitDirty, and optional ordinary branch, or pass false to opt out. The revision is unknown by default because ambient deploy/CI and observer working-directory metadata are ignored. Local Git discovery requires an explicit sourceDirectory (or RAINDROP_GIT_SOURCE_DIRECTORY); explicit RAINDROP_COMMIT_SHA values are honored. Automatic branch discovery requires detectBranch: true.
