npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@raindrop-ai/openai-managed-agents

v0.0.2

Published

Raindrop tracing for the OpenAI Agents API

Readme

Raindrop for the OpenAI Agents API

Capture the managed Agents API (openai.beta.agents.sessions) in Raindrop. This package uses openai, the OpenAI TypeScript SDK. For the separate, in-process @openai/agents framework, use @raindrop-ai/openai-agents.

Requires Node.js 22+ and OpenAI SDK 7.15.x–7.x.

pnpm add @raindrop-ai/openai-managed-agents openai

Quick start

import OpenAI from "openai";
import { createRaindropOpenAIManagedAgents } from "@raindrop-ai/openai-managed-agents";

const raindrop = createRaindropOpenAIManagedAgents({
  writeKey: process.env.RAINDROP_WRITE_KEY,
  userId: "user_123",
  properties: { feature: "world_builder" },
});
const client = raindrop.wrap(new OpenAI());

try {
  const events = await client.beta.agents.sessions.create({
    agent: { model: "gpt-6-astra", instructions: "Help build a simulation World." },
    environment: { type: "openai_hosted" },
    input: "Describe the files needed for a simulation World.",
    stream: true,
  });
  try {
    for await (const event of events) {
      if (event.type === "agent.session.turn.output_text.delta") process.stdout.write(event.delta);
      if (event.type === "agent.session.idle") break;
    }
  } finally {
    events.controller.abort();
  }
} finally {
  await raindrop.shutdown();
}

Use an OpenAI application key with the Agents API permissions. No OpenTelemetry setup is required. Missing or blank Raindrop keys disable cloud shipping. Set localWorkshopUrl: false to disable local Workshop mirroring.

Capture

  • One partial event per turn, completed when the native turn reaches a terminal state.
  • Session model, user input, completed final answer, per-turn usage, and provider attribution.
  • A root turn span and child command, function, MCP, search, and subagent-control tool spans.
  • Session and turn IDs in properties. By default, the session ID is the conversation ID.
  • Original OpenAI results, events, request options, abort controls, and response helpers.

The wrapper observes sessions.create, sessions.retrieve, sessions.events.create, sessions.events.stream, and sessions.stream. Use raindrop.wrap(client, { userId, convoId, eventName, properties }) for context on sessions created or retrieved through that wrapper. Use a single wrapper for each native client. Retrieve an existing session before following its events to capture its model. Reading raw bodies with asResponse() bypasses capture.

Reconnecting runners and stored history

For a runner that reconnects streams, use the public typed handler with an unwrapped native client. Keep one Raindrop client for the runner's lifetime:

import type { Turn } from "openai/resources/beta/agents/sessions/turns";

raindrop.handler.onSession(session);
raindrop.handler.onInput(session.id, userInput); // after successful submission
// Snapshot turn statuses before recovering their items.
const recoveredTurns: Turn[] = [];
for await (const turn of client.beta.agents.sessions.turns.list(session.id, { order: "asc" })) {
  recoveredTurns.push(turn);
}
for await (const item of client.beta.agents.sessions.items.list(session.id, { order: "asc" })) {
  raindrop.handler.onItem(session.id, item);
}
for (const turn of recoveredTurns) raindrop.handler.onTurn(turn);
for await (const event of events) raindrop.handler.onEvent(event);
await raindrop.flush();
// After all streams/recovery work are stopped:
raindrop.handler.forgetSession(session.id);
await raindrop.shutdown();

Open the stream before recovery so it can buffer live updates. Read and buffer turn statuses first, recover items next, then pass the buffered turns to the handler. A turn completed after the snapshot closes from its buffered live terminal event. Process callbacks serially during recovery and consumption.

onInputEvents(sessionId, events) records accepted message/tool-result submissions. Repeated terminal turns and tool receipts are deduplicated within this client. Turn deduplication retains the latest 10,000 completed turns. Across process restarts, provide a stable eventId: (turnId) => ... and replay items before turns. No session or item listing is intercepted automatically.

The wrapper closes unfinished captures when the last iterator for a session exits, including early exit and transport failure. This marks capture interruption; it does not cancel the backend turn. Session model and context remain available for later streams; the previous input is cleared. Metadata retains the latest 10,000 idle sessions plus sessions with active turns or streams. Call forgetSession when the session is no longer needed. Use the callback path when an unfinished turn must survive a reconnection.

Options and enrichment

Options include writeKey, endpoint, projectId, userId, convoId, eventName, properties, appGit, debug, localWorkshopUrl, maxTextFieldChars, eventId(turnId), and redact(text). Text uses the shared core bounds. redact applies to captured prompts, answers, tool payloads, and errors. Caller-supplied properties/attachments are the caller's responsibility.

events.patch, events.finish, events.addAttachments, events.setProperties, users.identify, and signals.track expose the shared core enrichment API. flush() ships current buffers; shutdown() also closes unfinished captures.

Limits

The service does not expose individual inference requests. Captures represent turns, rather than each hidden model call. Usage comes only from Turn.usage; missing usage stays missing. Session-wide cumulative counters are never used as turn usage. Usage is best effort and later revisions after the first terminal receipt are not applied.

Span timing reflects observed lifecycle events, including recovery; native turn timestamps are recorded as openai.turn.* attributes. Command duration is available in the native item. Image contents, reasoning text, intermediate commentary, agent-to-agent messages, and streaming text deltas are not automatically captured. Final text is read from completed final-answer items. Subagent turns are grouped by session and identified by subagent ID; no cross-turn parent hierarchy is inferred. Coordinator model identity is available from the session configuration. Subagent model and inherited coordinator input stay absent unless their own input is recorded.

See RELEASING.md for first-publication and verification steps. See the integration docs for configuration details.