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

@agentloop-sdk/anthropic

v0.1.1

Published

Drop-in Anthropic SDK wrapper for AgentLoop. Adds memory retrieval and turn logging to every messages.create call.

Readme

@agentloop-sdk/anthropic

Drop-in wrapper that adds AgentLoop memory retrieval and turn logging to every anthropic.messages.create call.

import Anthropic from "@anthropic-ai/sdk";
import { AgentLoop } from "@agentloop-sdk/core";
import { wrapAnthropic } from "@agentloop-sdk/anthropic";

const anthropic = wrapAnthropic(new Anthropic(), {
  loop: new AgentLoop({ apiKey: process.env.AGENTLOOP_API_KEY! }),
});

// Use exactly like the normal Anthropic SDK.
// Memory search fires before; logTurn fires after.
const msg = await anthropic.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [{ role: "user", content: "What's the Pix limit at night?" }],
});

That's the whole integration.

What happens under the hood

For every messages.create call, the wrapper:

  1. Extracts the last user message as the query
  2. Calls loop.search(query) — pulls any relevant corrections
  3. Appends them to your system prompt (or creates one if absent)
  4. Calls Anthropic with the augmented system prompt
  5. Calls loop.logTurn(question, answer) with the assembled text

If either AgentLoop call fails, your Anthropic call still succeeds — the hooks degrade gracefully.

Install

npm install @agentloop-sdk/core @agentloop-sdk/anthropic @anthropic-ai/sdk

All three are required. @anthropic-ai/sdk and @agentloop-sdk/core are peer deps so you pick the versions.

Per-call options

Pass an agentloop field alongside your normal Anthropic params. The wrapper strips it before forwarding (Anthropic rejects unknown fields).

const msg = await anthropic.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [...],
  agentloop: {
    userId: "u_123",                         // scope memory search + logTurn
    sessionId: "sess_abc",                   // passed to logTurn
    signals: { thumbs_down: true },          // merged with auto-detected
    metadata: { latency_budget_ms: 500 },    // stored with the turn
    skip: false,                             // true = bypass AgentLoop entirely
    search: false,                           // skip only retrieval (still logs)
    // or search: { limit: 5, tags: ["pix"] }
  },
});

Streaming

Streaming works — events yield to the caller in real time while the wrapper buffers text from content_block_delta events and fires logTurn after message_stop.

const stream = await anthropic.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [{ role: "user", content: question }],
  stream: true,
  agentloop: { userId: "u_123" },
});

for await (const event of stream) {
  if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
    process.stdout.write(event.delta.text);
  }
}
// logTurn has already fired with the full assembled text.

The wrapper yields every event type unchanged (message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop) — callers that depend on non-text events continue to work.

Configuration (passed at wrap time)

const anthropic = wrapAnthropic(new Anthropic(), {
  loop,

  // How to merge memories into the system prompt. Default appends a
  // "Trusted facts from past corrections:" block to a string system,
  // or to the last text block if system was an array.
  injectMemories: (memories, existingSystem) => {...},

  // Auto-detect signals from the response before logTurn.
  detectSignals: (question, answer, memories) => ({
    agent_punted: /not sure|contact support/i.test(answer),
    factual_claim: /\$|%|\d+\s*(day|hour|week)/i.test(answer),
  }),

  // Max memories per call. Default 3.
  searchLimit: 3,

  // Apply these tags to every memory search.
  searchTags: ["production"],

  // Only log turns when at least one signal fired. Default false.
  onlyLogWhenSignaled: false,
});

Low-level API

import { askWithAgentLoop } from "@agentloop-sdk/anthropic";

const resp = await askWithAgentLoop(
  anthropic,                    // raw, unwrapped Anthropic client
  {
    model: "claude-opus-4-7",
    max_tokens: 1024,
    messages: [{ role: "user", content: question }],
  },
  { userId: "u_123" },          // per-call options
  { loop }                      // wrap-time config
);

Not mutated

wrapAnthropic(client) returns a distinct Proxy. Your original client stays unwrapped and usable.

License

MIT