Documentation Index
Fetch the complete documentation index at: https://raindrop.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
Raindrop automatically instruments the OpenRouter Agent SDK (@openrouter/agent) to capture events and traces for model calls, tool execution, and multi-turn agent loops.
Installation
npm install @raindrop-ai/openrouter-agent @openrouter/agent
Quick Start
import { OpenRouter, tool } from "@openrouter/agent";
import { z } from "zod";
import { createRaindropOpenRouterAgent } from "@raindrop-ai/openrouter-agent";
const raindrop = createRaindropOpenRouterAgent({
writeKey: "your-write-key",
userId: "user-123",
convoId: "convo-456",
});
const openrouter = raindrop.wrap(
new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }),
);
const getWeather = tool({
name: "get_weather",
description: "Get the weather for a city.",
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({ forecast: z.string() }),
execute: async ({ city }) => ({ forecast: `Sunny in ${city}` }),
});
const result = openrouter.callModel({
model: "openai/gpt-4o-mini",
input: "Use get_weather for San Francisco, then answer briefly.",
tools: [getWeather] as const,
});
console.log(await result.getText());
await raindrop.shutdown();
Telemetry is finalized when the ModelResult is consumed with getText(), getResponse(), or a stream method.
Standalone callModel
If you import OpenRouter’s standalone callModel helper, wrap that function once and call the wrapped version:
import { OpenRouter, callModel } from "@openrouter/agent";
import { createRaindropOpenRouterAgent } from "@raindrop-ai/openrouter-agent";
const raindrop = createRaindropOpenRouterAgent({
writeKey: process.env.RAINDROP_WRITE_KEY,
userId: "user-123",
});
const trackedCallModel = raindrop.wrapCallModel(callModel);
const openrouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
const result = trackedCallModel(openrouter, {
model: "openai/gpt-4o-mini",
input: "Hello from OpenRouter",
});
console.log(await result.getText());
await raindrop.shutdown();
What Gets Traced
- Agent calls - input, output, model, response ID, response status, and token usage when OpenRouter returns it
- Tool calls - client tool executions captured as
ai.toolCall trace spans linked to the root event
- Conversation grouping - pass
convoId to group related agent calls
- Errors - failed OpenRouter calls finalize an error event before re-throwing to your application
- Signals and users - use the included
signals.track and users.identify APIs alongside automatic events
Tool spans are linked to the root event so you can inspect the full execution path in the Trace tab.
Configuration
const raindrop = createRaindropOpenRouterAgent({
writeKey: "your-write-key", // Optional: omit to disable telemetry
endpoint: "...", // Optional: custom Raindrop API endpoint
userId: "user-123", // Optional: associate events with a user
convoId: "convo-456", // Optional: conversation/thread ID
debug: false, // Optional: enable verbose logging
});
Identify Users
Associate traits with a user for filtering and trajectories:
await raindrop.users.identify({
userId: "user-123",
traits: {
plan: "pro",
company: "Acme",
},
});
Track Signals
Attach feedback, labels, or other signals to the most recently captured event:
if (raindrop.lastEventId) {
await raindrop.signals.track({
eventId: raindrop.lastEventId,
name: "thumbs_up",
type: "feedback",
sentiment: "POSITIVE",
});
}
Flushing and Shutdown
Always call flush() or shutdown() before your process exits to ensure all telemetry is shipped:
await raindrop.flush(); // flush pending data
await raindrop.shutdown(); // flush + release resources
Known Limitations
- Creating a
ModelResult without consuming it does not ship an event.
- Client tool spans wrap the local tool execution function, so their timing reflects local tool runtime.
- Server-executed OpenRouter tools are represented from response items when OpenRouter returns them after the provider response completes. Client function tools have the richest live trace data.