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

@opperai/agents

v0.3.0

Published

TypeScript SDK for building Opper AI agents

Readme

Opper Agent SDK (TypeScript)

Type‑safe, composable agents for Opper AI in TypeScript using: generics, Zod schemas, modular tools, and modern DX.

  • Async‑first
  • Strong typing with Zod runtime validation
  • Opper integration (spans, usage, retries)
  • Hooks for observability and custom behavior
  • Tools: function, decorator, MCP provider, or other agents via .asTool()

Installation

npm install @opperai/agents
# or
yarn add @opperai/agents
# or
pnpm add @opperai/agents

Prerequisites: Node.js 20+

Set your Opper API key:

export OPPER_API_KEY="your-api-key"

Get your API key from the Opper Dashboard.

Quick Start

To get started we recommend navigating to the examples/01_getting_started. They are designed to walk you through the different features of this SDK.

Minimal agent that returns structured JSON:

import { Agent } from "@opperai/agents";
import { z } from "zod";

const Output = z.object({ message: z.string() });

type OutputType = z.infer<typeof Output>;

const agent = new Agent<string, OutputType>({
  name: "HelloAgent",
  instructions: "Greet the user briefly.",
  outputSchema: Output,
});

const result = await agent.process("Say hi to Ada");
// => { message: "Hi Ada!" }

Tools

Define tools with Zod schemas. Results are discriminated unions that never throw.

import { createFunctionTool, ToolResultFactory, Agent } from "@opperai/agents";
import { z } from "zod";

const add = createFunctionTool(
  (input: { a: number; b: number }) => input.a + input.b,
  { name: "add", schema: z.object({ a: z.number(), b: z.number() }) },
);

const agent = new Agent<string, { answer: number }>({
  name: "MathAgent",
  instructions: "Use tools to compute when needed.",
  tools: [add],
  outputSchema: z.object({ answer: z.number() }),
});

const res = await agent.process("What is (5 + 3)? Return JSON with answer.");

Decorator tools and extraction:

import { tool, extractTools } from "@opperai/agents";
import { z } from "zod";

class WeatherTools {
  @tool({ schema: z.object({ city: z.string() }) })
  async get_weather({ city }: { city: string }) {
    return { city, tempC: 22 };
  }
}

const tools = extractTools(new WeatherTools());

Agent as Tool

Compose agents by reusing them as tools.

import { Agent } from "@opperai/agents";
import { z } from "zod";

const Summarize = new Agent<string, { summary: string }>({
  name: "Summarizer",
  instructions: "Summarize in one sentence.",
  outputSchema: z.object({ summary: z.string() }),
});

const Coordinator = new Agent<string, string>({
  name: "Coordinator",
  instructions: "Delegate to tools and answer.",
  tools: [Summarize.asTool("summarize")],
});

const answer = await Coordinator.process(
  "Summarize: Opper helps you build agents.",
);

MCP Integration

Wrap MCP servers as tool providers in one line.

import { mcp, MCPconfig, Agent } from "@opperai/agents";

const fsServer = MCPconfig({ name: "fs", transport: "stdio" });

const agent = new Agent<string, string>({
  name: "FSReader",
  instructions: "Use filesystem tools to answer questions.",
  tools: [mcp(fsServer)],
});

const out = await agent.process("Read README.md and summarize it.");

Hooks & Context

Observe the loop and collect metrics without breaking execution.

import { HookEvents } from "@opperai/agents";

agent.registerHook(HookEvents.LoopEnd, ({ context }) => {
  const last = context.executionHistory.at(-1);
  if (last) console.log("iteration", last.iteration);
});

AgentContext tracks usage automatically. Inspect it via hooks:

agent.registerHook(HookEvents.AgentEnd, ({ context }) => {
  console.log(context.usage); // { requests, inputTokens, outputTokens, totalTokens }
});

Streaming

Enable live token-by-token updates by setting enableStreaming: true on any agent. Both the think loop and the final result switch to the streaming API, emitting incremental events while still validating the final payload.

import { Agent, HookEvents } from "@opperai/agents";
import { z } from "zod";

const agent = new Agent({
  name: "StreamingAgent",
  enableStreaming: true,
  outputSchema: z.object({ answer: z.string() }),
  onStreamStart: ({ callType }) => {
    console.log(`[stream:start] ${callType}`);
  },
  onStreamChunk: ({ callType, accumulated }) => {
    if (callType === "final_result") {
      process.stdout.write(accumulated);
    }
  },
});

// Need to subscribe later? You can still use hooks or the event emitter.
agent.on(HookEvents.StreamChunk, ({ callType, fieldBuffers }) => {
  if (callType === "think") {
    console.debug(fieldBuffers.reasoning);
  }
});

See docs/streaming.md for hook payloads, JSON-path buffering, and usage tracking details.

Type Safety with Zod

  • Provide inputSchema/outputSchema to validate at runtime and type the agent at compile time.
  • Schemas with defaults/transforms are supported. If you use Zod defaults on fields (e.g., z.string().default("")), the agent will still deliver a fully‑typed output.

Testing & Tooling

pnpm install
pnpm lint
pnpm format
pnpm test
pnpm build
  • Tests use vitest and avoid real network calls.
  • Build bundles ESM/CJS and .d.ts into dist/ via tsup.

Examples

See examples/ for getting started, tools, composition, memory, and MCP usage. Run with pnpm build then tsx <file>.

License

MIT