Skip to main content

Installation

npm install @raindrop-ai/bedrock @aws-sdk/client-bedrock-runtime

Quick Start

import { createRaindropBedrock } from "@raindrop-ai/bedrock";
import { BedrockRuntimeClient, ConverseCommand } from "@aws-sdk/client-bedrock-runtime";

const raindrop = createRaindropBedrock({
  writeKey: "rk_...",
  userId: "user-123",
});

const client = new BedrockRuntimeClient({ region: "us-east-1" });
const wrapped = raindrop.wrap(client);

const response = await wrapped.send(
  new ConverseCommand({
    modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
    messages: [
      { role: "user", content: [{ text: "What is the capital of France?" }] },
    ],
  }),
);

console.log(response.output?.message?.content?.[0]?.text);
await raindrop.flush();

What Gets Traced

The Bedrock integration automatically captures:
  • Converse API — input messages, output text, model ID, token usage (inputTokens/outputTokens)
  • InvokeModel API — raw request/response, model ID, token usage (supports Claude, Titan, and Llama response formats)
  • Errors — captured with error status on the span, re-thrown to caller

Configuration

const raindrop = createRaindropBedrock({
  writeKey: "rk_...",       // Optional: your Raindrop write key (omit to disable telemetry)
  endpoint: "...",          // Optional: custom API endpoint
  userId: "user-123",      // Optional: associate events with a user
  convoId: "convo-456",    // Optional: conversation/thread ID
  debug: false,             // Optional: enable verbose logging
});

Using InvokeModel

The wrapper also supports the legacy InvokeModel API. Token usage extraction works with Claude, Titan, and Llama response formats:
import { InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime";

const response = await wrapped.send(
  new InvokeModelCommand({
    modelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
    contentType: "application/json",
    body: JSON.stringify({
      anthropic_version: "bedrock-2023-05-31",
      messages: [{ role: "user", content: "Hello!" }],
      max_tokens: 256,
    }),
  }),
);

const result = JSON.parse(new TextDecoder().decode(response.body));
console.log(result.content[0].text);
await raindrop.flush();

Flushing and Shutdown

Always call flush() before your process exits to ensure all telemetry is shipped:
await raindrop.flush();     // flush pending data
await raindrop.shutdown();  // flush + release resources